0

問題を引き起こすコードは次のとおりです。

class Base
{
public:
    virtual void fun()
    {
        cout<<"Base";
    }
};
class Der:public Base
{
    Base &pb;
public:
    Der(Base&b):pb(b){}
    virtual void fun()
    {
        cout<<"Der...";
        pb.fun();
    }
};
int main()
{
    Der(Der(Base())).fun();
    return 0;
}

このコードを実行すると、結果は「Der ... Base ...」と表示されます!これはすごいので、なぜ結果が論理的に正しい「Der ... Der ... Base」ではないのか理解できませんか?!次に、クラスDerのメンバーをに置き換え、Base&pbコードBase*pbを正当なものに変更します。最終的に、出力は「Der ... Der...Base」です。Base&pbコードをデバッグすると、を使用すると、Derのコンストラクターが使用中に1回だけ実行されBase*pb、コンストラクターが2回正しく実行されたことがわかりました。何が起こったのか、そしてその理由を私に説明できる人はいますか?

4

2 に答える 2

1

Der(Der(Base())).fun()式では、内部は-Der(Base())を生成します。rvalueコンパイラは、コピーの省略を使用してコードを最適化しオブジェクトの不要なコピーを削除します。

于 2012-11-18T14:11:29.263 に答える
0

@icepackの回答とコメント内の次の説明(要約:コードDer(der)はキャストであり、コンストラクターを使用して実現される場合とされない場合があります。あなたの場合はそうではありません)に加えて、回避策:意図を立てる必要がありますコンストラクターを使用しないことでクリアします。

私はあなたのコードを次のようなものに書き直します:

class Base
{
public:
    virtual void fun()
    {
        cout<<"Base";
    }
};

class Der:public Base
{
    Base &pb;
    Der(Base& b) : pb(b) {}
public:
    static Der Decorate(Base&& b){ return Der(b); }
    virtual void fun()
    {
        cout<<"Der...";
        pb.fun();
    }
};

int main()
{
    Der::Decorate(Der::Decorate(Base())).fun();
    return 0;
}

出力:Der ... Der ... Base)。


ポインタを受け入れるようにコードを変更するのは簡単です:

class Base
{
public:
    virtual void fun()
    {
        cout << "Base";
    }
};

class Der : public Base
{
    Base* pb;
    Der(Base* b) : pb(b) {}
public:
    static Der Decorate(Base* b){ return Der(b); }
    virtual void fun()
    {
        cout << "Der...";
        pb->fun();
    }
};

int main()
{
    Der::Decorate(&Der::Decorate(&Base())).fun();
    return 0;
}
于 2012-11-18T15:01:53.837 に答える