虚函数原理
虚函数的一般实现模型:每个类有一个虚函数表,内含该类中有作用的虚函数地址。每个 对象有一个vptr(虚函数表指针)指向虚函数表
如下Person类
class Person { public: virtual ~Person(); virtual string& getName(); virtual string& setName(); protected: string name_; };
在Person的对象Jack中,有两个东西,一个是数据成员name_,一个是_Vptr_Person(指向虚函数表的指针),其中_Vptr_Person存储着以下东西:
如果Man集成class Person,Man如下所示:
class Man:Person { public: ~Man(); string& getName(); protected: string hasWhat_; //有什么呢 哈哈 };在Man对象Star中有三个东西,一个是从Person中继承而来的name_,一个是自己的hasWhat,都是数据成员,另一个为_Vptr_Man(虚函数表指针):
其中,如果Man类里面重写了Person类里面的虚函数,则虚函数表被重写函数的对应位置替换为派生类里面的函数地址,如Man的虚函数表中,将Person::~Person() Person::getName();的地址替换为Man::~Man() 和Man::getName(),没有重写的则依旧为基类虚函数的地址
而且,此时,Man类可作为基类,继续被继承,满足如上关系。
若派生类继承多个具有虚函数的类,因为需要向上类型转换,所以派生类里面就有多个虚函数指针。则其结构体大小会增加一个虚函数指针的大小,如下代码所示:
class A { virtual void f() { } }; class B { virtual void g(); }; class C:public B { }; class D:public B,public A { }; int main () { cout<<sizeof(A)<<endl;//A中没有成员变量,只有一个虚函数表指针 cout<<sizeof(B)<<endl;//同A cout<<sizeof(C)<<endl;//继承了B 有一个虚函数表指针 cout<<sizeof(D)<<endl;//继承了A 和 B,有两个虚函数表指针 return 0; }
注意:虚函数指针在类中的位置,取决于编译器具体实现,不过一般虚函数表指针的位置在类的首部,即类最开始的位置。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u013507368/article/details/48032307