zoukankan      html  css  js  c++  java
  • C++虚拟继承

    假设我们有类 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;  
    }
    
  • 相关阅读:
    spring MVC框架(入门篇)-1
    spring的三种注入方式
    mybitis实现增,删,改,查,模糊查询的两种方式:(2)
    [JavaEE] 20141228_Java类文章搜集
    [JavaEE] Apache Maven 入门篇(下)
    [JavaEE] Apache Maven 入门篇(上)
    [ASP.Net] MVC2,3,4,5的不同
    [JavaEE] Mybatis与Ibatis比较
    [ASP.Net] 转 > ASP.NET MVC 大牛之路
    [ASP.Net] 转 > ASP.NET MVC 小牛之路
  • 原文地址:https://www.cnblogs.com/GyForever1004/p/8436992.html
Copyright © 2011-2022 走看看