c++, 虚基派生 : 共同基类产生的二义性的解决办法

虚基派生 //虚继承

#include <iostream>
using namespace std;
#include <string>
//--------------------------------------
class A
{
public:
    int m_ax ;
    int m_ay;

    A();
    A(int va,int vy);

    void show();
};
A::A()
{

}
A::A(int vx,int vy)
{
    this->m_ax = vx;
    this->m_ay = vy;
}
void A::show()
{
    cout<<"A::show "<<endl;
    cout<<"A::m_ax = "<<m_ax<<endl;
    cout<<"A::m_ay = "<<m_ay<<endl;
}
//--------------------------------------
class B1: virtual public A {
public:
    int m_b1x;
    B1();
    B1(int ax,int ay,int bx);

};
B1::B1()
{

}

B1::B1(int ax,int ay,int b1x)
{
    m_ax = ax;
    m_ay = ay;
    m_b1x = b1x;
}

//---------------------------------------
class B2: virtual public A {
public:
    int m_b2x;

    B2();
    B2(int ax,int ay,int b2x);

};
B2::B2()
{

}

B2::B2(int ax,int ay,int b2x)
{
    m_ax = ax;
    m_ay = ay;
    m_b2x = b2x;
}

//-------------------------------------
class C: public B1,public B2 {//虚基继承
public:
    int m_cx;

    C();
    C(int ax,int ay,int b1x,int b2x);

    void show();
};
C::C()
{

}

C::C(int ax,int ay,int b1x,int b2x)
{
    m_ax = ax;//因为C的上级B1、B2使用了虚基继承A,所以C类中只有一个m_ax,不会产生二义性。
    m_ay = ay;
    m_b1x = b1x;
    m_b2x = b2x;
}
void C::show()
{
    cout<<"C::show()"<<endl;
    cout<<"m_ax = "<<m_ax<<endl;
    cout<<"m_ay = "<<m_ay<<endl;
    cout<<"m_b1x = "<<m_b1x<<endl;
    cout<<"m_b2x = "<<m_b2x<<endl;
}
//--------------------------------------
int main()
{
    C c1(1 ,2 ,3 ,4 );

    c1.show();    //C中实现的show
    c1.A::show(); //从A继承下来的show只有一个,以下面这三种方式访问到的都是同一个A::show()
    c1.B1::show();
    c1.B2::show();

    cout<<"addr c1.B1::m_ax = "<<&(c1.B1::m_ax)<<endl;//从A继承下来的m_ax只有一个,这三种方式访问的是同一个m_ax,地址是相同的。
    cout<<"addr c1.B2::m_ax = "<<&(c1.B2::m_ax)<<endl;
    cout<<"addr c1.A::m_ax = "<<&(c1.A::m_ax)<<endl;

    cout<<"c1.B1::m_ax = "<<c1.B1::m_ax<<endl;
    cout<<"c1.B2::m_ax = "<<c1.B2::m_ax<<endl;
    cout<<"c1.A::m_ax = "<<c1.A::m_ax<<endl;


    B1 b1(22,33,44) ;
    cout<<"B1.m_ax = "<<b1.m_ax<<endl;
    b1.show();//B虚继承A ,可以不用重写A的方法而直接使用。

    while(1);
    return 0 ;
}

// C::show()
// m_ax = 1
// m_ay = 2
// m_b1x = 3
// m_b2x = 4
// 
// A::show 
// A::m_ax = 1
// A::m_ay = 2
// 
// A::show 
// A::m_ax = 1
// A::m_ay = 2
// 
// A::show 
// A::m_ax = 1
// A::m_ay = 2
// 
// addr c1.B1::m_ax = 0xbfbb43c8  //因为C的上级B1、B2使用了虚基继承A,所以C类中只有一个m_ax,不会产生二义性。
// addr c1.B2::m_ax = 0xbfbb43c8
// addr c1.A::m_ax = 0xbfbb43c8
// c1.B1::m_ax = 1
// c1.B2::m_ax = 1
// c1.A::m_ax = 1
// 
// B1.m_ax = 22
// A::show 
// A::m_ax = 22
// A::m_ay = 33

参考:华清远见笔记。

原文地址:https://www.cnblogs.com/mylinux/p/4096926.html