菱形继承 虚继承

发布于:2025-07-20 ⋅ 阅读:(11) ⋅ 点赞:(0)

菱形继承 虚继承

在c++中,在使用多继承时如果发生类A排石出类B和类C,类D继承自类B和类C,这是就发生菱形继承。

在这里插入图片描述

如果这时D调用A那编译器就发生了混乱,它不知道要用B中的A还是C中的A。

验证代码如下

//菱形继承
class A {
    protected:
    int m_a;
};
//直接基类B
class B : public A {
    protected:
    int m_B;
};
class C : public A {
    protected:
    int m_C;
};
class D : public B,public C {
public:
    void srtA(int A) {
       //错误的方式 m_a=A;

        //正确的方式——需要进行声明或者使用虚继承
        B::m_a=A;
    }
    void setB(int B) {
        m_B = B;
    }
    void setc(int c) {
        m_C = c;
    }
    void setD(int D) {
        m_D = D;
    }
private:
int m_D;
};

很好虽然用进行声明的方式可以解决,但是又会出现另一个问题,就是数据冗余,为了解决菱形继承出现的数据冗余的问题C++提出了虚继承,虚继承使得派生类中只保留一份间接成员

需要用到 virtual

语法

class B:virtual public A{

};

我们把之前的代码改一改发现果然解决了问题


//菱形继承
class A {
    protected:
    int m_a;
};
//直接基类B
class B : virtual public A {
    protected:
    int m_B;
};//这里改了
class C : virtual public A {
    protected:
    int m_C;
};//这里改了
class D : public B,public C {
public:
    void srtA(int A) {
        m_a=A;
    }
    void setB(int B) {
        m_B = B;
    }
    void setc(int c) {
        m_C = c;
    }
    void setD(int D) {
        m_D = D;
    }
private:
int m_D;
};
int main() {
    D d;
    return 0;
}

虚继承构造函数

在序继承中,虚基类是由最终的派生类初始化的。

简单点说就是由最后一次子类初始化他才会改变。


#include <iostream>
#include <bits/ostream.tcc>
using namespace std;
//菱形继承
class A {
    protected:
    int m_a;
public:
    A(int a):m_a(a){}
    void print() {
        cout<<this->m_a<<endl;
    }
};
//直接基类B
class B : virtual public A {
    protected:
    int m_B;
    public:
    B(int a,int b):A(a),m_B(b){}
    void print() {
        cout<<this->m_a<<" "<<this->m_B<<endl;
    }
};
class C : virtual public A {
    protected:
    int m_C;
public:
    C(int a,int c):A(a),m_C(c){}
    void print() {
        cout<<this->m_a<<" "<<this->m_C<<endl;
    }
};
class D : public B,public C {
public:
    D(int a,int b,int c,int d):
A(a),B(90,b),C(100,c),m_D(d){}
//在这里虽然赋过90和100 但是这里赋值不作数
    void srtA(int A) {
        m_a=A;
    }
    void setB(int B) {
        m_B = B;
    }
    void setc(int c) {
        m_C = c;
    }
    void setD(int D) {
        m_D = D;
    }
    void print() {
        cout<<this->m_a<<" "<<this->m_B<<" "<<this->m_C<<" "<<this->m_D<<endl;
    }

private:
int m_D;

};
int main() {
   A a1(111);
    a1.print();
    B b1(222 ,333);
    b1.print();
    C c1(444 ,555);
    c1.print();
    D d1(666,777,888,999);
    d1.print();
    return 0;
}

这篇博客到这里就结束了喜欢记得点赞哦(๑′ᴗ‵๑)I Lᵒᵛᵉᵧₒᵤ❤


网站公告

今日签到

点亮在社区的每一天
去签到