虚表机制

普通继承

此种情况下对象模型是简单的

#include<iostream>
class Top
{
    public: 
        int a;
};
class Left:public Top
{
    public:
        int b;
};
class Right:public Top
{
    public:
        int c;
};
class Bottom:public Left, public Right
{
    public:
        int d;
};

int main()
{
    std::cout << "hello world!" << std::endl;
    /*
    对象模型:
    Top         Left            Right           Bottom
    Top::a      Top::a          Top::a          Left::Top::a
                Left::b         Right::c        Left::b
                                                Right::Top::a
                                                Right::c
                                                Bottom::d
    */
    Left* left = new Left();
    Top* top = left;    //指针向上转型
    //std::cout << top->a << std::endl;   //ok
    //std::cout << top->b << std::endl;   //err:类Top没有b成员
    std::cout << "指针left的值:" << left << "  指针top的值:" << top << std::endl; //两值相同

    Bottom* bottom = new Bottom();
    left = bottom;  //指针向上转型
    //std::cout << left->a << std::endl;   //ok
    //std::cout << left->b << std::endl;   //ok
    //std::cout << left->d << std::endl;   //err:类Left没有d成员
    std::cout << "指针bottom的值:" << bottom << "  指针left的值:" << left << std::endl; //两值相同

    Right* right = bottom;  //指针向上转型
    //std::cout << right->a << std::endl;   //ok
    //std::cout << right->c << std::endl;   //ok
    //std::cout << right->d << std::endl;   //err:类Right没有d成员
    std::cout << "指针bottom的值:" << bottom << "  指针right的值:" << right << std::endl; //两值不同,right=bottom+偏移量8

    //top = bottom;   //err:基类Top不明确,'Top' is an ambiguous base of 'Bottom'
    Top* topL = (Left*) bottom;    //ok
    Top* topR = (Right*) bottom;   //ok
    std::cout << "指针topL的值:" << bottom << "  指针left的值:" << left << std::endl; //两值相同
    std::cout << "指针topR的值:" << bottom << "  指针right的值:" << right << std::endl; //两值相同

    return 0;
}

虚继承

虚继承可以用来避免重复继承

//虚继承可以避免重复继承基类
#include<iostream>
class Top
{
    public:
        int a;
};
class Left:virtual public Top
{
    public:
        int b;
};
class Right:virtual public Top
{
    public:
        int c;
};
class Bottom:public Left, public Right
{
    public:
        int d;
};

int main()
{
    std::cout << "hello world!" << std::endl;
    /*
    对象模型:
    Top            
    Top::a:int

    Left                         points to        vtable for Left                            
    vptr.Left:vtable for Left----------------->virtual base offset:int=8
    Left::b:int                                offset to top:int=0
    Top::a:int                                 typeinfo:typeinfo for Left

    Right                          points to        vtable for Right                 
    vptr.Right:vtable for Right----------------->virtual base offset:int=8
    Right::c:int                                 offset to top:int=0
    Top::a:int                                   typeinfo:typeinfo for Right

    Bottom                          points to           vtable for Bottom
    vptr.Left:vtable for Bottom-------------------->virtual base offset:int=20
    Left::b:int                     points to       offset to top:int=0
    vptr.Right:vtable for Bottom---------+          typeinfo:typeinfo for Bottom
    Right::c:int                         +--------> virtual base offset:int=12
    Bottom::d:int                                   offset to top:int=8
    Top::a:int                                      typeinfo:typeinfo for Bottom
    */
    Bottom* bottom = new Bottom();
    Left* left = bottom;
    //std::cout << left->a << std::endl;   //ok
    //std::cout << left->b << std::endl;   //ok
    //std::cout << left->d << std::endl;   //err:类Left没有d成员
    std::cout << "指针bottom的值:" << bottom << "  指针left的值:" << left << std::endl; //两值相同,left=bottom
    std::cout << "left->b的地址值:" << &left->b << "  left->a的地址值:" << &left->a << std::endl; //两值不同

    Right* right =bottom;
    //std::cout << right->a << std::endl;   //ok
    //std::cout << right->c << std::endl;   //ok
    //std::cout << right->d << std::endl;   //err:类Right没有d成员
    std::cout << "指针bottom的值:" << bottom << "  指针right的值:" << right << std::endl; //两值不同,right=bottom+偏移量16
    std::cout << "right->c的地址值:" << &right->c << "  right->a的地址值:" << &right->a << std::endl; //两值不同
    std::cout << "bottom->b的地址值:" << &bottom->b << "  bottom->c的地址值:" << &bottom->c << "  bottom->d的地址值:" << &bottom->d << "  bottom->a的地址值:" << &bottom->a <<std::endl;

    left = new Left();
    //std::cout << left->a << std::endl;   //ok
    //std::cout << left->b << std::endl;   //ok
    //std::cout << left->d << std::endl;   //err:类Left没有d成员
    std::cout << "left的地址:" << left << "  left->b的地址值:" << &left->b << "  left->a的地址值:" << &left->a << std::endl; //两值不同

    return 0;
}

参考:https://www.cnblogs.com/qg-whz/p/4909359.html
https://www.oschina.net/translate/cpp-virtual-inheritance?comments&p=5

全部评论

相关推荐

11-15 18:39
已编辑
西安交通大学 Java
全村最靓的仔仔:卧槽,佬啥bg呢,本也是西交么
点赞 评论 收藏
分享
在评审的大师兄很完美:像这种一般就是部门不匹配 转移至其他部门然后挂掉 我就是这样被挂了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务