2012-02-08 14 views
-3

これははるかに大きなコードのダウンサイズの問題です。私はC.aがヒープ上になければならないことを知っていますが、私は変更を避けたい " " - >"をコード内のどこにでも置くことができます。このバグを回避できる方法はありますか?私はこのことを可能にするが、適切に動作しませんC++以来のバグを検討 ...C++の継承はスタック上で動作していませんか?

#include <iostream> 
using namespace std; 

class AA { 
public: 
    virtual void foo() { 
     cout << "AA!\n"; 
    }; 
}; 

class AB : public AA { 
public: 
    AB() : AA() { cout << "construct AB!\n"; } 

    void foo() { 
     cout << "AB!\n"; 
    } 
}; 

class C { 
public: 
    AA a; 
    void xchg() { 
     a.~AA(); 
     new (&a) AB(); // everything works here except virtuals 
    } 
}; 

int main() { 
    C c; 
    c.a.foo(); // -> AA 
    c.xchg(); 
    c.a.foo(); // -> AA :(

    AA *aa = new AB(); 
    aa->foo(); // -> AB (virtual works) 

    return 0; 
}; 
+0

ご希望の場合は、使用するだけです。代わりに - >なぜ単に参照を使用していないのですか?ヒープ上にオブジェクトを作成し、それを使用したいときはローカル参照に割り当てます。 – Nerdtron

+0

Nerdtron、これはクラスでは動作しません。 AA * _a; AA&a = * _a; 今_aはconstである必要があります。 – chhu79

+0

@ chuu79:なぜうまくいかないのですか?はい、 '_a'は別のメモリ位置を指すことはできませんが、その場所に新しいオブジェクトを作成することができます。一方、タイプを変更することはまだ違法です。先週の質問にちょうど答えました。 –

答えて

1

のみバグがあなたのコードである(コンパイラがg ++ 4.6.1です)。あなたは未定義のビヘイビアを呼び出しています(いくつかの異なる方法で、実際には)。

スタンダードはこれを診断する必要はありませんが、あなたが愚かなことをしないようにすることはコンパイラの責任ではありません。

+1

あまりにも悪い!コンパイラがスタックポインタへの書き込みアクセスをブロックすることができないのは残念です... – chhu79

+1

@ chuu79:どのようなスタックポインタですか?なぜスタックへのアクセスをブロックすべきですか?あなたはこれについて非常に珍しい(そして間違った)考え方を持っています。 –

1
new (&a) AB(); // everything works here except virtuals 

これは実際には機能しません。ここでの動作は未定義です。 aは、タイプAAのオブジェクトです。代わりにタイプABのオブジェクトを構築することはできません。そこに構築できるオブジェクトの種類はAAです。

aの多態性が必要な場合は、動的に割り当てられたオブジェクトへのポインタを使用する必要があります。好ましくは、動的に割り当てられたオブジェクトへのスマートポインタ、例えばstd::unique_ptr<AA>AAには仮想デストラクタが必要です。

関連する問題