请告诉我为什么以下程序的输出如下。我没有在c ++中获得虚拟类。请遵守以下代码:
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: public B
{ };
class D: public B
{ };
class E
: public C
, public D
{ };
int main()
{
E e;
C &c = e;
D &d = e;
std::cout << c.get_c();
d.set_c('b');
std::cout << c.get_c() << std::endl;
return 0;
}
O / P:aa
我希望输出为ab。得到“aa”的原因是什么?
如果我有c.set_c('b')而不是d.set_c('b')那么我会得到O / P:“ab”,这里也是,我不知道为什么会这样。 c,d都只指一个对象。
class C:virtual public B{};
class D:virtual public B{};
如果C类,D类几乎从B继承,那么 O / P永远是“ab”
答案 0 :(得分:9)
B
中有两份E
,一份来自C
,另一份来自D
。当您致电d.set_c('b')
时,您正在修改m_c
D
中的B
。当您致电c.get_c()
时,您会在m_c
C
中获得B
,而C
尚未更改。
当您D
和B
虚拟地从B
继承时,它会解决问题,因为E
只有{{1}}的一个副本1}}。
这是相关的:http://www.parashift.com/c++-faq/virtual-inheritance-where.html
答案 1 :(得分:1)
我不确定我是否理解这个问题,但你的问题包含了答案,将B声明为C和D的虚拟基础并且你得到了。
#include <iostream>
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;
};
// note virtual inheritance
class C: virtual public B
{ };
// note virtual inheritance
class D: virtual public B
{ };
class E
: public C
, public D
{ };
int main()
{
E e;
C &c = e;
D &d = e;
std::cout << c.get_c() << std::endl;;
d.set_c('d');
std::cout << c.get_c() << std::endl;
c.set_c('c');
std::cout << d.get_c() << std::endl;
return 0;
}
导致你想要的输出,不是吗?
a
d
c
答案 2 :(得分:1)
考虑class C : public B
和C* c = new C
,然后c
指向以B
开头的存储,因为C*
也是B*
。对于true
,这是class D : public B
。
现在适用于class E : public C, public D
和E* e = new E()
。 e
的记忆就像:
{| B of C | other members of C }{| B of D | other members of D}
正如您在上面的案例中所见,我们有B
的一个C
实例和D
的另一个实例,现在很明显当你只调用((D*)e)->set_c( 'b' )
时更改B
的{{1}}实例和D
B
实例将保持不变。
现在,当您说C
时,C ++与class C : public virtual B
实际上从B
继承的其他类共享B
个实例。所以在这种情况下e
类似于:
| shared B |
| C members | | D members |
正如您所看到的,我们只有一个B
,因此调用((C*)e)->set_c
和((D*)e)->set_c
将同时B
。