一.多态性的概念
多态性是指一个名字,多种语义;或界面相同,多种实现。其中重载函数是多态性的一种简单形式。虚函数允许函数调用与函数体的联系在运行时才进行,称为动态联编。二.虚函数
标志: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; }小总结:
其实到现在我也还是没能很好地理解多态的使用方法,但是我知道它的作用还是很大的。比如系统一般都会有客户端和后台管理端,这就需要用多态实现不同的登录界面。所以学会多态还是很重要的。但是我对多态的理解就是用基类里面的虚函数向外扩展,实现同一个函数的不同功能实现。实际应用还是比较缺乏的。所以还是得加深理解。考完试了也知道自己什么水平了,还是好好学习吧。
