多态学习总结

一.多态性的概念

  • 多态性是指一个名字,多种语义;或界面相同,多种实现。其中重载函数是多态性的一种简单形式。
  • 虚函数允许函数调用与函数体的联系在运行时才进行,称为动态联编

二.虚函数

  • 标志:virtual
  • 虚函数的作用就是实现多态性----以共同的方法,对不同的对象采取不同的策略
  • 定义:虚函数只能是类中的成员函数,而且不能是静态的。
  • 语法:

class 类名

{

    ....virtual 返回类型 函数名(形式参数列表);//虚函数

}

  • 注意,virtual只能在类内使用。不能将友元说明为虚函数,但虚函数可以是另一个类的友元。
  •  析构函数可以是虚函数,但构造函数不能是虚函数。
  • 当在派生类中相同的重载函数都保持虚特性。
  • 在派生类中重载基类的虚函数要求函数名、返回类型、参数个数和参数类型和顺序完全相同。
  •  如果仅仅返回类型不同,C++认为是错误重载;如果函数原型不同,仅函数名相同,丢失虚特性 。
  • 使用虚函数并不一定产生多态,也不一定使用动态联编。例如,在调用中对虚函数成员使用成员名限定,可以强制C++对该函数的调用使用静态联编
  • 例子:
#include<iostream>
using namespace std;
class Point//表示平面上的点
{
    private:
        double x,y;//坐标值
    public:
        Point(double x1=0,double y1=0):x(x1),y(y1){}
        virtual double area(){return 0;}//虚函数
};
class Circle:public Point//圆
{
    double r;//半径
    public:
    Circle(double x,double y,double r1):Point(x,y),r(r1){}
    virtual double area{return 3.14*r*r;}//虚函数
};
int main()
{
    Point a(2.5,2.5);
    Circle c(2.5,2.5,1);
    Point *pc=&c;
    cout<<"Circle area="<<pc->area()<<endl;//动态联编
    cout<<"Circle area="<<pc->Point::area()<<endl;//静态联编
    return 0;
}
  • 虚函数实现多态的条件:

1.类之间的关系满足赋值兼容性规则;

2.改写了同名的虚函数;

3.根据赋值兼容性规则使用指针(或引用)。

注意:必须同时满足以上三条才能保证实现动态联编。

  • 第三条分为两种情况:

1.使用基类指针或引用访问虚函数。例如:

Point *p=new Circle;//基类指针指向派生类

cout<<p->area();//动态联编

2.把指针或引用作为函数参数,这个函数不一定是类的成员函数,可以是普通函数,而且可以重载。例如:

void fun(Point *p)

{cout<<p->area();}//动态联编

  • 在派生类中,当一个指向基类成员函数的指针指向一个虚函数,并且通过指向对象的基类指针或引用访问这个虚函数时,仍将发生多态性。
#include<iostream>
using namespace std;
class Base
{
    public:
        virtual void print{cout<<"Base"<<endl;}
};
class Derived:public Base
{
    public:
        void Print(){cout<<"Derived"<<endl;}
};
void display(Base *p,viod(Base::*pf)())
{
    (p->*pf)();
}
int main()
{
    Derived d;
    Base b;
    display(&d,&Base::print);
    display(&b,&Base::print);
    return 0;
}
  • 析构函数可以是虚的。虚析构函数用于指引 delete 运算符正确析构动态对象 。
#include<iostream>
using namespace std ;
class A
{
    public:
        ~A(){cout<<"A::~A() is called.\n";}
};
class B : public A
{ 
    public:
        ~B(){cout<<"B::~B() is called.\n";}
};
int main()
{
    A *Ap = new B;	
    B *Bp2 = new B;
    cout<<"delete first object:\n";
    delete Ap;
    cout<<"delete second object:\n";
    delete Bp2;
} 

三.纯虚函数和抽象类

  • 纯虚函数是一种特殊的虚函数。在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实

现留给该基类的派生类去做。

  • 纯虚函数是一个在基类中说明的虚函数,在基类中没有定义, 要求任何派生类都定义自己的版本。
  • 纯虚函数为各派生类提供一个公共界面。
  • 纯虚函数说明形式:

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

  • 一个具有纯虚函数的基类称为抽象类。
#include<iostream>
using namespace std;
class Sharp//抽象类
{
    public:
        virtual double area() =0;//纯虚函数
        virtual double volumn() =0;//纯虚函数
};
class Circle:public Sharp//圆
{
    public:
        Circle(double a):r(a) {}
        virtual double area(){return 2*3.1415926*r;}//虚函数
        virtual double volumn(){return 0;}//虚函数
    private:
        double r;
};
class Cylinder:public Circle//圆柱体
{
    public:
        Cylinder(double a,double b):Circle(a),h(b) {}
        virtual double volumn() {return area()*h;}//虚函数
    private:
        double h;
};
int main()
{
    Circle a(10.0);
    Cylinder b(5.6,10.5);
    cout<<a.area()<<","<<b.volumn()<<endl;//静态联编
    Sharp *pb;//定义基类指针
    pb=&b;
    pb=&b;
    cout<<pb->area()<<","<<pb->volumn()<<endl;//动态联编
    return 0;
}

小总结:

    其实到现在我也还是没能很好地理解多态的使用方法,但是我知道它的作用还是很大的。比如系统一般都会有客户端和后台管理端,这就需要用多态实现不同的登录界面。所以学会多态还是很重要的。但是我对多态的理解就是用基类里面的虚函数向外扩展,实现同一个函数的不同功能实现。实际应用还是比较缺乏的。所以还是得加深理解。考完试了也知道自己什么水平了,还是好好学习吧。


  
  
  









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值