- 締切済み
キャストによるアドレス変更について
多重継承クラスのインスタンスのポインタを基底クラスのポインタ に代入するとき、キャストで、vtableへのポインタを変更するために、 多重継承クラスのインスタンスのポインタのアドレスから4byte加算 したアドレスが、基底クラスのポインタに代入されます。 以下のプログラムは、多重継承ではないですが、pCのポインタの アドレスに4byte加算してpAに代入されます。pAのデストラク タはvirtual宣言していないので、pAが指すアドレスにはvtable のポインタはないはずですが、4byte加算するという動作が起こるのは 何故でしょうか。 #include <iostream.h> class AAA { public: AAA(){} ~AAA(){} }; class BBB:public AAA { public: BBB(){} virtual ~BBB(){} }; class CCC:public BBB { public: CCC(){} ~CCC(){} }; int main(void) { CCC *pC = new CCC(); AAA *pA = (AAA *)(pC); delete pA; return 0; }
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- mha01
- ベストアンサー率81% (9/11)
ただいまC++を勉強中の身なんでアレなんですけど、大城正典著”詳説C++”(第2版)のp.193~p.195に、 ■仮想関数とthisポインタの関係 「…オブジェクトの先頭アドレスと基底型サブオブジェクトの先頭アドレスが等しいことを前提にしたプログラムは書いてはいけません。 C言語プログラマはキャスト演算子でポインタの型を安易に変換してしまいがちですが、…」 の辺りにその理由が書いてありましたよ。内容は長くなるんで本を読んでください。(本質てきなところは、No.1さんの回答していることと同じです)
- Yune-Kichi
- ベストアンサー率74% (465/626)
BBBの構造が,vtableが前に来てAAAの内容がvtableの後に来る実装になっているのでしょう。 言語仕様上,vtableについて触れられているわけではありません。 つまり,vtableの配置については実装者に一任です。 要求された動作さえ満たせばよいのですから。 もっと言うと,仮想関数の実装にvtableを使う必要すらありません。 # 現実的には他の方法はほとんど選択されませんが。