5

请告诉我为什么以下程序的输出如下。我没有得到 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”

4

3 回答 3

9

Bin有两份E,一份是 via C,一份是 via D。当您调用时d.set_c('b'),您正在修改m_cinDB。当你打电话时c.get_c(),你会得到m_cin CB它没有改变。

当您从虚拟中创建CD继承时B,它解决了问题,因为只有一个Bin副本E

这是相关的:http: //www.parashift.com/c++-faq/virtual-inheritance-where.html

于 2012-10-02T18:09:59.787 回答
1

考虑class C : public B然后指向一个以 as 开头C* c = new C的存储也是。这是为了cBC*B*trueclass D : public B.

现在为class E : public C, public DE* e = new E()。记忆e是这样的:

{| B of C | other members of C }{| B of D | other members of D}

正如您在上面的例子中看到的那样,我们有 2 个实例,B一个用于C,另一个用于D,现在很明显,当您调用时,((D*)e)->set_c( 'b' )您只更改B实例,D并且B实例C将保持不变。

现在当你说class C : public virtual B,C++B与任何其他虚拟继承的类共享实例B。所以在这种情况下e是这样的:

           | shared B |
    | C members | | D members |

正如你所看到的,我们只有一个B这样的呼唤((C*)e)->set_c,并且((D*)e)->set_c都将采取同样的行动B

于 2012-10-02T18:35:04.757 回答
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
于 2012-10-02T18:09:47.110 回答