首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

头疼的虚函数有关问题

2012-03-23 
头疼的虚函数问题classBase{public:virtualvoidOutput(){printf( Base::Output\n )}}classBaseEx{publ

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

热点排行