定义一个父类
class Person{ public: virtual void f(){cout << "use f()" << endl;} virtual void g(){cout << "use g()" << endl;} virtual void h(){cout << "use h()" << endl;} };
父类对象其在内存中布局如下:
class Bag:public Person{ public: virtual void i(){cout << "use i()" << endl;} virtual void j(){cout << "use j()" << endl;} };
可以看出虚函数表内的虚函数是按声明顺序进行排序的
父类虚函数排在子类虚函数之前
class Bag:public Person{ public: void f(){cout << "class Bag use fun" << endl;} virtual void i(){cout << "use i()" << endl;} virtual void j(){cout << "use j()" << endl;} };
子类覆盖的虚函数,放在父类原先放该虚函数的位置上。
所以当父类指针指向该子类对象时,会调用该子类的重载函数
子类的虚函数放在第一张虚函数表中,紧跟着第一个父类的虚函数
如果每个父类都有虚函数,则有几个父类就有几张虚函数表
父类的虚函数被子类覆盖后,则该子类对应的重载函数的位置在被覆盖的父类函数的位置上。(如果父类没有该虚函数,则不用被覆盖)
父类的虚函数被子类覆盖后,则父类指针指向该子类对象时,调用的f()便是子类中重载的f()
#include <iostream> using namespace std; class Person1{ public: virtual void f(){} virtual void g(){} virtual void h(){} virtual ~Person1(){} }; class Person2{ public: virtual void f(){} virtual void g(){} virtual void h(){} void a(){ // 成员函数,不需要重载 cout << "class Person2" << endl; } virtual ~Person2(){} }; class Person3{ public: virtual void g(){} virtual void h(){} virtual ~Person3(){} }; class Bag:public Person1, public Person2, public Person3{ public: void f(){ cout << "Bag f()" << endl; } void g(){ cout << "Bag g()" << endl; } void a(){ cout << "Class Bag" << endl; } }; int main(int argc, char const *argv[]) { Person3* p3 = new Bag; //p3->f(); // P3 没有成员函数f() // 多态首先得是 父类有虚函数,其次是子类要定义该函数的重载 // 如果父类的虚函数改为成员函数,则子类无法进行重载,即无法实现多态 delete p3; p3 = NULL; Person1* p1 = new Bag; p1->f(); delete p1; p1 = NULL; Person2* p2 = new Bag; p2->a(); delete p2; p2 = NULL; return 0; }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。