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」を取得する理由は何でしょうか?

d.set_c('b')の代わりにc.set_c('b')を使用している場合、O / P: "ab"が表示されます。ここでも、なぜそうなのかわかりません。c、dは両方とも1つのオブジェクトのみを参照しています。

class C:virtual public B{};
class D:virtual public B{};

クラスC、クラスDが仮想的にBから継承されている場合、O/Pは常に「ab」になります。

4

3 に答える 3

9

Binの2つのコピーがあります。1Eつはvia C、もう1つはviaDです。を呼び出すと、のd.set_c('b')が変更m_cされます。を呼び出すと、変更されていないin 'sが表示されます。DBc.get_c()m_cCB

を仮想的に作成して継承するCと、のコピーが1つしかないため、問題が解決します。DBBE

これは関連しています:http://www.parashift.com/c++-faq/virtual-inheritance-where.html

于 2012-10-02T18:09:59.787 に答える
1

検討class C : public Bしてから、sinceisで始まるストレージをポイントC* c = new Cします。これはのためです。cBC*B*trueclass 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}

上記の場合にわかるように、BforCとforの2つのインスタンスがありDます。呼び出したときにインスタンスを((D*)e)->set_c( 'b' )変更するだけで、のインスタンスは変更されないままになることは明らかです。BDBC

今あなたが言うときclass C : public virtual B、C++Bは仮想的にから継承する他のクラスとインスタンスを共有しますB。したがって、この場合eは次のようになります。

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

ご覧のとおり、Bこのように呼び出す((C*)e)->set_cのは1つだけで、((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 に答える