2011-07-06 11 views
0
struct A { 
    B b; 
    A(int x):b(x){} 
    A(int x, float g) // how to implement this? I want to init b as a C. 
}; 
struct B { 
    enum {e_c, e_d} type; 
    int i; 
    B(int i_):i(i_){} 
}; 
struct C : public B { 
    float f; 
    C(int i_, float f_):B(i),f(f_){} 
}; 
struct D : public B { 
    double ff; 
    D(int i_, double d):B(i),ff(d){} 
}; 

おそらくこれをコード化する別の方法がありますか?元々私はクラスBを持っていましたが、私はそれを分割して、(互換性のない/相互排他的な)フィールドをBに追加しないようにしました。私の解決策は、Aがbを使用するときにbの列挙をチェックして、その後、B *をC *またはD *にキャストして浮動小数点または倍精度を取得します。私の問題は今、私はAに初期化をさせる方法を知らない。言語は私にそれのような何かをさせることさえできますか?サブクラスのctorで初期化する

編集:私は、AのbがCまたはDの余分なフィールドを許可するためのスペースを割り当てられていない可能性があることを認識しました。 floatやdoubleを格納するための空き容量はありません。だから私は欲しいことをする正しい方法は、Bにunion {float f; double ff;};を追加することだと思いますか?

+0

あなたは 'B'型の実際のオブジェクトメンバを持っているので、' '' 'C''として" b "を初期化することはできません!あなたは**オブジェクトを 'B *'にすることができますが、なぜ型 'C'のメンバーを直接作るのはなぜですか? –

+0

とにかく、可能な派生クラスを列挙するための基本クラスの列挙を持つことは、今後のデザインカークラッシュのような匂いを抱かせる。あなたが実際の問題を投稿した場合、我々はよりよい解決法について考えることができます。 –

+0

私はフレーズ私の質問に別の方法を推測する:より多くのOOPの方法は、労働組合を行うにはありますか?私は、私が組合を使用すると、この例のように浮動小数点数と二重整数を持ち、浮動小数点値として二重値を解釈すると、私はゴミを取得することになることを知っています厄介なバグ。 –

答えて

2

あなたの例はちょっと混乱しています。しかし、ポインターが必要なのでしょうか?あなたがこれを行う場合、B必見は仮想デストラクタを持っていることを

struct A { 
    B *b; 
    A(int x):b(new B(x)) {} 
    A(int x, float g):b(new C(x,g)) {} 
    ~A() { delete b; } // Very important! 
}; 

は注意してください。また、Aオブジェクトのコピーが何を意味するのか考える必要があります。

+0

** 'B'仮想デストラクタを付ける必要があります! :-)そして、あなたがそれにいる間に 'A'をコピーできないようにしてください。また、Bに列挙型を入れるOPの考えは、今後の悪いデザインの選択のように見える。 –

+0

@Kerrek:ああ、良い点は、バーチャルdtorがOPコードから抜けていたことに気付かなかった。コピーの作成/割り当ては簡単に接線の庭の道を導くことができますが、私はそれについても言及します。 –

1

あなたの編集は正しいです。

あなたが望むことを行う通常の方法は、Bを(できればスマートな)ポインタで格納し、それぞれのコンストラクタに適切な型を割り当てることです。

関連する問題