虚函数 : 在函数前面加一个virtual, 这个函数就是一个虚函数
class Person{ public: virtual void BuyTicket(){ cout << " " << endl; } };
多态的条件:
0.前提 : 要有继承
1.有虚函数
2.子类重写父类的虚函数
3.调用此函数的类型是基类的指针或者引用
#include<iostream> using namespace std; class Person{ public: virtual void BuyTicket(){ cout << "买全票" << endl; } }; class Student :public Person{ public: virtual void BuyTicket(){ cout << "买半票" << endl; } }; void fun(Person& p){ p.BuyTicket(); } void test(){ Person p; Student s; fun(p); fun(s); } int main(){ test(); system("pause"); return 0; }
虚函数的重写: 子类定义一个和父类接口完全相同的函数
重写的虚函数的两种形式 :
相同 : 函数名, 参数列表, 返回值类型和父类对应的函数完全一致
class Person{ public: virtual void BuyTicket(){ cout << "买全票" << endl; } }; class Student :public Person{ public: virtual void BuyTicket(){ cout << "买半票" << endl; } };
协变 : 函数名, 参数列表和父类对应的函数完全一致,但返回值类型可以不同, 但必须是有继承关系的指针/引用
class A{}; class B :public A{}; class Person{ public: virtual A* BuyTicket(){ cout << "买全票" << endl; return new A; } }; class Student :public Person{ public: virtual B* BuyTicket(){ cout << "买半票" << endl; return new B; } };
final:
class 类名 final : 此类是不能被继承的类
virtual void fun() final :表示此虚函数不能被重写, 在父类中使用
虚函数 + override :强制重写父类的一个虚函数, 子类中使用
接口继承 : 目的是为了重写, 达成多态
#include<iostream> using namespace std; //抽象类: 类中定义了纯虚函数 class A{ public: //纯虚函数: 函数 = 0 virtual void fun() = 0; }; class B:public A{ public: virtual void fun(){ cout << "B::fun()" << endl; } }; class C :public A{ public: virtual void fun(){ cout << "C::fun()" << endl; } }; void test(){ //抽象类不能实例化 //A* p = new A; A* pa = new B; A* pa1 = new C; pa->fun(); pa1->fun(); } int main(){ test(); system("pause"); return 0; }
1. 只要类中有虚函数, 类对象中都会有一个虚表指针成员: __vfptr : 二级指针-->函数指针指针
2. 虚表是虚函数指针数组, 虚表中不存放普通函数指针
3. 子类会继承父类的虚表
4. 子类的虚表中, 如果有重写的虚函数, 对应的函数指针也会被子类的虚函数指针覆盖
5. 虚表没有存放在对象中, 在代码段中

浙公网安备 33010602011771号