c ++虚拟类:有趣的一点

ran*_*111 5 c++ polymorphism virtual virtual-inheritance

请告诉我为什么以下程序的输出如下.我没有在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;
}
Run Code Online (Sandbox Code Playgroud)

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{};
Run Code Online (Sandbox Code Playgroud)

如果C类,D类几乎从B继承,则O/P将始终为"ab"

Stu*_*etz 9

有两个Bin E,一个via C和一个via D.当你打电话d.set_c('b'),你在修改m_cDB.当你打电话c.get_c(),你再拿到m_cCB,这并没有改变.

当你从虚拟中制作CD继承时B,它解决了问题,因为那时只有一个Bin的副本E.

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


Big*_*oss 1

考虑class C : public B然后指向以“since is 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}
Run Code Online (Sandbox Code Playgroud)

正如你在上面的例子中看到的,我们有 2 个实例,B一个 forC另一个 for 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 |
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我们只有一个B这样的调用((C*)e)->set_c,并且((D*)e)->set_c都会执行相同的操作B