读书人

头疼的虚函数有关问题

发布时间: 2012-03-23 12:06:21 作者: rapoo

头疼的虚函数问题
class Base
{
public:
virtual void Output()
{
printf( "Base::Output\n ");
}
};

class BaseEx
{
public:
virtual void Print()
{
printf( "BaseEx::Print\n ");
}
};

class Derive : public Base, public BaseEx
{
public:
void QI(void ** p)
{
*p = (Base*)this;
}
};

int main(int argc, char* argv[])
{
Derive obj;
BaseEx * p;
obj.QI((void**)&p);
p-> Print();
return 0;
}
为什么会调用BASE的Output,如果将Print将virtual去掉,就调用
BaseEx的print函数,请高手帮忙解答

[解决办法]
因为多继承的内存布局可能是:

vptr base1 ------ cast to base1* 得到的指针
data base1
vptr base2 ------ cast to base2* 得到的指针
data base2
...
data drived

而虚函数的调用只是查 vptr 表。查的那个对象的 vptr 表就调那个函数了。

详解见 《深度探索 C++ 对象模型》 4.2 多继承下的 virtual fucntion
[解决办法]
代码有太多的问题 :
1. base, baseEx需要有virtual destructor.
2. 不要假设C++编译出来的内存布局 -〉(Base*)this; 使用dynamic_cast
3. QI返回裸指针,非常危险,使用具有引用计数的智能指针等
4. QI返回指针,用户不知道对象在stack还是在heap里,不知道是不是该调用delete 还是由stack自己管理。
5. int main(int argc, char* argv[]) --> 其中argc,argv编译会提示unreferenced parameters等,如果将warning level 设的比较高的话。

读书人网 >C++

热点推荐