2011-01-17 4 views
2

私はC++を学び、良い多型コードを書こうとしていて、混乱している。私は "Generator"と "Triggerable"の2つのスーパークラスを持つクラスEr_1Sineを持っています。C++:オブジェクトを別のスーパークラスにキャストすると、異なるポインタアドレスが返される

Er_1Sineは次のようになります。

class Er_1Sine : public Generator, public Triggerable{ 

} 

私は「ER1」に設定する、「ジェネレータ」ポインタ(GEN)を作成した場合、ポインタアドレスが「ER1」のアドレスと一致しました。しかし、私の "Triggerable"ポインタのアドレス "trig"は一致しません。何が起きてる? er1とgenが同じオブジェクトを指していないtrigですか?

er1 = new Er_1Sine(); 
Generator *gen = er1; 
Triggerable *trig = er1; 

printf("\n\n er1 as Er_1Sine: %p \n", er1); 
// outputs: "er1 as Er_1Sine: 0x4d28920" 

printf("er1 as Generator address: %p \n", gen); 
// outputs: "er1 as Generator address: 0x4d28920" 

printf("er1 as Triggerable address: %p \n\n", trig); 
// outputs: er1 as Triggerable address: 0x4d289f8 

答えて

4

完全にの場合、化合物クラスは、2つの別々のオブジェクトが互いに重なっていると考えることができます。あなたが最初にトップ(同じアドレス)で宣言したものと、その下に2番目に宣言したもの(したがって別のアドレス)。

5

これは、複数の継承ベースのサブオブジェクトが子インスタンスと異なるオフセットにあり、したがって異なるアドレスです。暗黙的なアップキャスト中にポインタの値を調整する必要があるのは、コンパイラのフロントエンドです。

+0

私はこれを追加したいと思います。このような理由から、ポインタ値に==を指定しないでください。おそらく、Javaのようなアプローチを取って、等価関数や演算子を書く方が良いでしょう。 –

+0

ええと、はい、いいえ。ポインタの比較は組込み操作であり、オーバーライドすることはできません。インスタンスを比較するには、おそらくカスタム演算子のセットが必要です。ここにJavaのようなものはありません... :) –

+0

実際にポインタの等価性に==を使用すると、ポインタが同じオブジェクトを指しているかどうかを判断するのに一般的に完璧です。標準を正しく読んでいるとポインタは比較できる同じ型(可能な型変換の後)であるので、この場合、基本クラスポインタを派生クラス1と比較すると、後で暗黙的に基底クラスにキャストされる(したがってそれに応じて調整される)ので、両方同じ派生オブジェクトから生成されます。 – Grizzly

1

1つのポインタがクラスの一部のGeneratorを指しており、もう1つのポインタがTriggerableの部分を指しています。 GeneratorとTriggerableは異なるため、同じポインタにすることはできません。

1

複数の継承では、異なる基本クラスは、子オブジェクト内で異なるメモリアドレスを持つことができます。

関連する問題