我理解的是,在E对象中,C和D对象分别由c和d引用。但是我无法理解为什么d.set_c('b')无法将B.m_c初始化为'b',因为c.set_n(3)能够将A.m_n的值更改为3。
#include <iostream>
class A
{
public:
A(int n = 2) : m_n(n) {}
public:
int get_n() const { return m_n; }
void set_n(int n) { m_n = n; }
private:
int m_n;
};
class B
{
public:
B(char c = 'a') : m_c(c) {}
public:
char get_c() const { return m_c; }
void set_c(char c) { m_c = c; }
private:
char m_c;
};
class C
: virtual public A
, public B
{ };
class D
: virtual public A
, public B
{ };
class E
: public C
, public D
{ };
int main()
{
E e; //object of E is created
C &c = e; //c is used to refrence C object in E Object
D &d = e; //c and d has same inheritance structure
std::cout << c.get_c() << d.get_n();
c.set_n(3);
d.set_c('b');
std::cout << c.get_c() << d.get_n() << std::endl;
return 0;
}
答案 0 :(得分:3)
让我们看看你的类结构,如果你创建一个E
的实例,你最终会得到一个如下所示的对象层次结构:
class B class A class B
\ / \ /
\ / \ /
\ / \ /
class C class D
\ /
\ /
\ /
class E
您会看到B
有两个实例,但只有A
的一个实例。这是因为虚拟继承。 C
和D
都使用虚拟继承从A
继承,因此A
中只有e
的一个实例。
现在让我们看一下用户代码:
E e;
C &c = e; // reference C in the object hierarchy of E
D &d = e; // reference D in the object hierarchy of E
c.set_n(3); // set the value in the only instance of A in E
d.set_c('b'); // set the value of one of the two instances of B in your e
std::cout << c.get_c(); // print the value in the other instance of B in e
// not the one you set before
std::cout << d.get_n(); // print the value of the only instance of A in e
// this got changed before
答案 1 :(得分:1)
类E
的对象包含C
和D
子对象,每个子对象都包含一个B
子对象。由于没有关于B
的虚拟继承,C
和D
中的每一个都包含自己的B
副本。
d.set_c()
然后引用B
中包含的D
并更新,c.get_c()
引用B
中包含的C
,它独立于D
中的那个,因此没有改变。
对于类A
及其成员n
,没有这样的问题,因为使用了虚拟继承。这样可以确保在类E
的最终对象中,每个人都只使用一个子对象A
,无论通过哪个“路径”进行访问。
答案 2 :(得分:0)
更改
, public B
到
, virtual public B
获取输出a2b3
。
在您的示例中,E
实例包含用于分隔B
个实例。