头疼的虚函数问题
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 设的比较高的话。