手机版
你好,游客 登录 注册 搜索
背景:
阅读新闻

C++虚拟继承深入认识

[日期:2018-02-12] 来源:Linux社区  作者:GyForever1004 [字体: ]

假设我们有类 A 、类 B 和类 Test ,类 Test 具有类 A 和类 B 的全部属性,并且它们都具有 temp 属性,现在我们需要在类 Test 中实现对 temp 属性的设定与读取,故写出以下程序:

#include <iostream>

class Base{
public:
    int temp;
};

class A : public Base{
};

class B : public Base{
};

class Test : public A, public B{
public:
    void setValue(int val){
        temp = val;
    }

    void print(){
        std::cout << temp << std::endl;
    }

};

int main()
{
    Test T = Test();

    T.setValue(1004);
    T.print();

    return 0;
}

费了好大力气写出来的程序,保存后编译居然挂了 0.0

这是因为多重继承使基类拷贝了多次,最后子类调用相同属性的话就会产生二义性的问题。

对于上面的程序我们可以这样更改使之编译通过:

class Test : public A, public B{
public:
    void setValue(int val){
        A::temp = val;
    }

    void print(){
        std::cout << B::temp << std::endl;
    }

};

程序输出为0。

这样就解决了二义性的问题,但这样的代码显得臃肿,而且相同的属性被拷贝了多次还会浪费内存。

虚拟继承就可以轻松解决上面出现的问题,子类依旧继承基类,但此时不是内存的拷贝,而是指向基类的指针,占用一份指针的内存。

虚拟继承程序如下:

#include <iostream>

class Base{
public:
    int temp;
};

class A : virtual public Base{
};

class B : virtual public Base{
};

class Test : public A, public B{
public:
    void setValue(int val){
        temp = val;
    }

    void print(){
        std::cout << temp << std::endl;
    }

};

int main()
{
    Test T = Test();

    T.setValue(1004);
    T.print();

    return 0;
}

应用虚继承的方式,既解决了二义性的问题,也解决了资源浪费的问题,美滋滋~

温馨提示:

虚拟继承虽好,但是不能贪杯,在开发过程中我们应该避免使用多重继承,它会使得程序变得更加复杂,故出错的可能性就更高。

补充虚继承内存占用大小(32位机,from百科):

#include <iostream>  

using namespace std;  
  
/* 大小为4 */
class A
{  
public:  
    int a;  
};  

/* 大小为12,变量a,b共8字节,虚基类表指针4 */
class B :virtual public A  
{  
public:  
    int b;  
};  

/* 与B一样12 */
class C :virtual public A  
{  
public:  
    int c;  
};  

/* 24,变量a,b,c,d共16,B的虚基类指针4,C的虚基类指针4 */
class D :public B, public C  
{  
public:  
    int d;  
};  
  
int main()  
{  
    A a;  
    B b;  
    C c;  
    D d;  
    
    cout << sizeof(a) << endl;  
    cout << sizeof(b) << endl;  
    cout << sizeof(c) << endl;  
    cout << sizeof(d) << endl;  

    return 0;  
}

本文永久更新链接地址http://www.linuxidc.com/Linux/2018-02/150902.htm

linux
相关资讯       C++虚拟继承 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参��本评论即表明您已经阅读并接受上述条款