C++中的多态表现在同一语句表现出不同的形态。
我们知道,C++编译器是通过virtual关键字实现的多态,即C++编译器会默认为我们添加一个VPTR指针在对象里面,并且维护一个VTABLE的结构,VPTR指针就指向这么一个结构,这个结构里面存放这所有virtual关键字的函数。当执行某个语句时就是通过对象的VPTR指针来找到对应的virtual方法,来实现多态的。
在这里,我想验证一下,所谓的VPTR指针是实实在在存在的。代码如下:
#include <iostream>
using namespace std;
class Parent
{
public:
Parent(int a = 0)
{
this->a = a;
cout<<"Parent()"<<endl;
}
void print()
{
cout<<"Parent a="<<a<<endl;
}
private:
int a;
};
class Child
{
public:
Child(int b = 0)
{
this->b = b;
cout<<"Child()"<<endl;
}
virtual void print()
{
cout<<"Child b = "<<b<<endl;
}
private:
int b;
};
int main(void)
{
cout<<"*p ="<<sizeof(char *)<<endl;
cout<<"Parent size="<<sizeof(Parent)<<endl;
cout<<"Child size="<<sizeof(Child)<<endl;
return 0;
}
编译运行,结果如下:
分析结果我们发现,相同的类成员,加了virtual关键字的比没加关键字的多了12个字节的数据,因为我的机器是64位,默认8字节对齐的,所以其实Child类比Parent类多8个字节的数据,如第一条打印,指针大小正是8个字节。所以,我们可以得出结论。C++编译器为我们默认加了VPTR指针,来实现多态。
正如之前博文所说,不加virtual关键字,是静态联编,即C++编译器在编译阶段就绑定了调用原则。而加了virtual关键字是动态联编,即在运行期间根据对象类型,找到对象的VPTR指针,再找到VTABLE结构,去找到所要调用的方法,这样就实现了C++中强大的多态机制。