c++学习笔记(五)

多态性与虚函数

多态性是指具有不同功能的函数可以用同一个函数名。

虚函数是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。

(1).在基类用virtual声明成员函数为虚函数。在类外定义虚函数时不必加virtual。

(2).在派生类中重新定义虚函数时,要求函数名、函数类型、函数参数个数和类型全部与基类的虚函数一样。可根据需要重新定函数体。

一个成员函数被声明为虚函数时,其派生类中的同名函数都自动成为虚函数。

(3).定义一个基类对象的指针变量并使他指向其某一派生类的对象。

确定调用具体对象的过程称为关联。

在编译时可确定调用的虚函数属于哪一个类,其过程称为静态关联;在运行时进行关联的称为早期关联。函数重载属于静态关联。

在编译程序时系统就能决定调用的是哪个函数,静态多态又称编译时的多态性,静态多态性是通过函数重载实现的。动态多态性是在程序运行过程中才动态确定操作所针对的对象的。又称运行时的多态性。

例:

#include <iostream>

using namespace std;
//定义基类Point
class Point
{
    public:
        Point(){ }
        virtual ~Point()   //Pointl类的析构函数
        {
            cout<<"1.Point"<<endl;
        }
};
//定义派生类Circle
class Circle:public Point
{
    public:
        Circle(){ }
        ~Circle()  //Circle类的析构函数
        {
            cout<<"2.Circle"<<endl;
        }
};
int main()
{
    Point *p = new Circle; //用new开辟Circle类对象的动态存储空间
    delete p;        //用delete释放动态存储空间
    return 0;
}

输出结果为:
2.Circle
1.Point
纯虚函数与抽象类:

纯虚函数:

纯虚函数是在声明虚函数时被初始化为“0”的函数。

Virtual 函数类型  函数名  (参数列表) = 0;

(1).纯虚函数没有函数体。

(2).最后面的“=0”并不表示函数返回值为0,他只是形式上的作用,标志这是纯虚函数。

(3).纯虚函数的作用,在基类中保留一个函数名字,方便派生类根据需要定义。

抽象类:

不用来定义对象,而只作为一种基本类型用作继承的类称为抽象类。

派生类对基类(抽象类)的所有虚函数进行了定义,则这个派生类不是抽象类。如果派生类只定以基类的部分抽象类,则这个派生类仍然为抽象类。

实例:

抽象基类Shape(形状),Point(点),Circle(圆),Cylinder(圆柱体)都是Shape类的直接派生类。

#include <iostream>
using namespace std;
//声明抽象基类Shape
class Shape
{
    public:
        virtual float area() const   //虚函数
        {
            return 0.0;
        }
        virtual float volume() const  //虚函数
        {
            return 0.0;
        }
        virtual void shapeName() const = 0;  //纯虚函数
};
//声明Point类
class Point:public Shape
{
    public:
        Point(float=0,float=0);
        void setPoint(float,float);
        float getX() const { return x; }
        float getY() const { return y; }
        virtual void shapeName() const { cout<<"Point:"; }
        friend ostream & operator << (ostream & output,const Point &);
    protected:
        float x,y;
};
//定义Point类成员函数
Point::Point(float a,float b)
{
    x = a;
    y = b;
}
void Point::setPoint(float a,float b)
{
    x = a;
    y = b;
}
ostream & operator << (ostream & output,const Point &p )
{
    output<<"["<<p.x<<","<<p.y<<"]";
    return output;
}
// 声明 Circle类
class Circle:public Point
{
    public:
        Circle(float x = 0,float y = 0,float r = 0);
        void setRadius(float);      //设置半径
        float getRadius() const;
        virtual float area() const;
        virtual void shapeName() const { cout<<"Circle"; } //对虚函数进行再定义
        friend ostream& operator << (ostream & output,const Circle &);
    protected:
        float radius;
};
Circle::Circle(float x,float y,float r):Point(x,y),radius(r) {}
void Circle::setRadius(float r)
{
    radius = r;
}
float Circle::getRadius() const { return radius; }
float Circle::area() const { return 3.14159 * radius*radius; }
ostream &operator <<(ostream & output,const Circle &c)
{
    output<<"["<<c.x<<","<<c.y<<"],r="<<c.radius;
    return output;
}
//声明Cyclinder类
class Cylinder : public Circle
{
    public:
        Cylinder (float x = 0,float y = 0,float r = 0,float h = 0);
        void setHeight(float);
        virtual float area() const;
        virtual float volume() const;
        virtual void shapeName() const { cout<<"Cylinder"; } //对虚函数进行再定义
        friend ostream & operator << (ostream & ,const Cylinder &);
    protected:
        float height;
};
//定义Cylinder成员函数
Cylinder::Cylinder(float a,float b,float r,float h):Circle(a,b,r),height(h){}
void Cylinder::setHeight(float h) { height = h; }
float Cylinder::area() const
{
    return 2*Circle::area()+2*3.14159*radius*height;
}
float Cylinder::volume() const
{
    return Circle::area()*height;
}
ostream &operator<<(ostream & output,const Cylinder&cy)
{
    output<<"["<<cy.x<<","<<cy.y<<"],r="<<cy.radius<<",h="<<cy.height;
    return output;
}
int main()
{
    Point point(3.2,4.5);  //建立Point对象
    Circle circle(2.4,1.2,5.6); //建立Circle类对象
    Cylinder  cylinder(3.2,6.4,5.2,10.5);  //建立Cylinder对象
    point.shapeName();   //静态关联
    cout<<point<<endl;

    circle.shapeName(); //静态关联
    cout<<cylinder<<endl<<endl;

    Shape *pt;   //定义基类指针

    pt = &point;    //指针指向Point
    pt->shapeName();  //动态关联
    cout<<"x="<<point.getX()<<"y="<<point.getY()<<"\narea="<<pt->area()<<"\nvolume="<<pt->volume()<<"\n\n";

    pt = &circle;  //指针指向Circle类对象
    pt->shapeName();  //动态关联
    cout<<"x="<<circle.getX()<<"y="<<circle.getY()<<"\narea="<<pt->area()<<"\nvolume="<<pt->volume()<<"\n\n";

    pt = &cylinder;  //指针指向Cylinder类对象
    pt->shapeName();  //动态关联
    cout<<"x="<<cylinder.getX()<<"y="<<cylinder.getY()<<"\narea="<<pt->area()<<"\nvolume="<<pt->volume()<<"\n\n";

    return 0;
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值