多态的实现原理
2016-08-20 19:11
417 查看
多态的实现原理是通过虚函数表和vptr指针实现的
多态的三个条件:1.继承,2.虚函数重写,3.父类指针或引用指向子类对象class Parent { public: virtual void func() { cout<<"parent::func()"<<endl; } virtual void func(int i) { cout<<"parent::func(int i)"<<endl; } }; class Child:public Parent { public: virtual void func() { cout<<"Child::func()"<<endl; } virtual void func(int i) { cout<<"child::func(int i)"<<endl; } };
当类中声明虚函数时,编译器会在类中生成一个虚函数表;
虚函数表是一个存储类成员函数指针的数据结构;
虚函数表是由编译器自动生成与维护的;
virtual成员函数会被编译器放入虚函数表中;
存在虚函数时,每个对象中都有一个指向虚函数表的指针(vptr)
此时从上面的代码中就可以在编译器中生成下列表:
VTABLE:
void Parent::func()
void Parent::func(int)
void Child::func()
void Child::func(int)
所以:
Parent对象的VPTR指针指向了VTABLE中的Parent数据;
Child对象的VPTR指针指向了VTABLE表中的Child数据;
最后在调用时:
void run(Parent*p) { p->func(); }
此时编译器就会根据func是否为虚函数来进行相应的解释:
1.如果不是虚函数:编译器可直接确定被调用的成员函数(也叫做静态联编)
2.如果是虚函数:编译器根据对象p的VPTR指针所指向的虚函数表中来查找func函数并调用(也叫做动态联编或者迟邦定)
注意:通过虚函数表指针VPTR调用重写函数是在程序运行时进行的,因此需要通过寻址操作才能确定真正应该调用的函数,而普通成员函数是在编译器时就确定了调用谁,因此虚函数的效率要低很多,所以不是虚函数越多越好。
下面来证明VPTR指针的存在。
class Parent1 { public: Parent1(int a=0) { this->a=a; } void print() { cout<<"我是爹"<<endl; } private: int a; }; class Parent2 { public: Parent2(int a=0) { this->a=a; } virtual void print() { cout<<"我也是爹"<<endl; } parent: int a; }; int main() { cout<<"sizeof(Parent1):"<<sizeof(Parent1)<<endl; cout<<"sizeof(Parent2):"<<sizeof(Parent2)<<endl; return 0; }
第一个Parent1是没有虚函数,所以输出的是4
第二个Parent2是含有虚函数,所以输出的是4+sizeof(VPTR)=8;
因此只要定义了虚函数编译器就自动生成了VPTR指针。
相关文章推荐
- C++中多态实现的内部原理
- 理解C++的多态原理及实现
- C++多态的实现原理(转)
- C++多态的实现及原理详细解析
- C++多态的实现原理
- C++多态如何实现 | sys_brk原理
- C++多态的实现原理
- C++多态的实现原理
- C++多态的实现原理
- C++多态的实现原理
- C++多态的实现原理
- 利用override多态原理实现对相似页面的后台代码的抽象,并实现动态GridView动态列数据绑定
- C++中多态的实现原理
- C++多态的实现原理
- C++多态的实现原理,C++中虚函数和多态
- c++实现多态的原理和机制
- (转)C++中多态的实现原理
- C++的多态原理和实现
- 多态实现原理
- C++多态的实现原理