为什么要有虚函数?
看这段代码:
void main()
{
CShape aShape;
CEllipse aEllipse;
CCircle aCircle;
CTriangle aTriangle;
CRect aRect;
CSquare aSquare;
CShape * pShape[6] = {&aShape,&aEllipse,&aCircle.&aTriangle,&aRect,&aSquare};
for(int i=0;i<6;i++)
{
pShape[i]->display();
}
}
这段代码中,CShape 是其它几个类的基类.每个类中都有一个display()函数.
如果没有虚函数的方法的话,那么for循环中那句pShape[i]->display()都会调用基类CShape中的那个display().
如果它们都是虚函数的话,那么它们将分别调用其派生类中自己的display()函数.
为什么要用虚函数表的方法来实现虚函数的功能?
c++中是使用虚函数表和虚指针的方法来实现虚函数的功能的.为什么选择这种方法呢?为什么编译不在编译阶段来调用相应派生类的中display()呢?
在上例中也许可以,编译器也许可以根据变量名找到其类型,然后在编译阶段找到其中display()函数地址并调用相应代码.但是对于下面的这种情形,
编译器无法确定调用哪个派生类的代码.
void chooseDisplay(CShape* aShape)
{
aShape->display();
}
chooseDisplay()函数这段代码怎么编译?编译器无法为它生成代码.
所以c++设计了vtbl+vtpr的方法. 即类中拥有一个vtbl,这个vtbl中包含所有虚函数的地址.排列顺序是虚函数在类中的声明顺序.
每个类的对象拥有一个vtpr,指向这个类的vtbl, 这个vtpr必须是位于对象实例空间的最前面的位置.
详情请参见 http://blog.csdn.net/hairetz/archive/2009/04/29/4137000.aspx
注意点:
当建立一个基类引用对象,赋给它一个派生类对象的话,那么它可以实现虚函数的功能.