クラスの継承について – プログラミング – Home

通知
すべてクリア

[解決済] クラスの継承について


夢幻
 夢幻
(@夢幻)
ゲスト
結合: 22年前
投稿: 22
Topic starter  

以下のようなクラスを定義して各基本クラスへのポインタにキャストした時のアドレスが
ずれてしまいました。いろいろ試してみて[class C]の基本クラスのを指定する順番を
変えた時に、後ろ側のクラス型にキャストした時に発生することが解りました。
自分としてはクラスAもBも基本クラスなので問題なくキャスト出来るものだと思っていました。
何故こうなるのかご教授願います。

以下が実行結果と実際のコードです。

//---実行結果---
&d = 12feec
pA = 12feec
pB = 12fef4
pC = 12feec
//--------------

#include <stdio.h>
class A
{
public:
int a;
A(){}
virtual ~A(){}
};

class B
{
public:
int b;
B(){}
virtual ~B(){}
};

class C : public A,public B
{
public:
int c;
C(){}
virtual ~C(){}
};

class D : public C
{
public:
int d;
D(){}
virtual ~D(){}
};

void main()
{
D d;

A* pA = &d;
B* pB = &d;
C* pC = &d;
char str[128];
sprintf(str,&d = %x\npA = %x\npB = %x\npC = %x\n,&d,pA,pB,pC);
printf(str);

}


引用未解決
トピックタグ
PAI
 PAI
(@PAI)
ゲスト
結合: 23年前
投稿: 359
 

ストラウストラップのThe Annotated C++ Reference Manual
(註解 C++リファレンスマニュアル)の 10.3c あたりが参考になると思います。

多重継承の場合、キャストはポインタの値を変更し得ます。

この例でいくと C のインスタンスのメモリ割り当ての内部のどこかに
A 部分と B の部分がそれぞれ別々に出来上がります。
そしてキャストを行った場合 A の部分の先頭、B の部分の先頭を
それぞれ指します。

|<----------------- D -------------------------------->|
|<--- A --->|<--- B --->|<-- Cの残り-->|<-- Dの残り -->|
↑ココ   ↑ココ

// 多重継承時の基底クラスのメンバの配置順は既定されていないので
// 必ずこのようになるとは限りませんが。


返信引用
夢幻
 夢幻
(@夢幻)
ゲスト
結合: 22年前
投稿: 22
Topic starter  

なるほど、そうだったのですか。
ポインタの値が変化することを知らなかったので、
かなり無茶なことをしていたようです。

明示的にキャストしたアドレスを使用するようにしたら
うまくいくようになりました。


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

わざわざ明示的にキャストせずとも,問題なく動きますよ。
#明示的にreinterpret_castすると問題になりますが……。

継承関係がある型のポインタ間で明示的なキャストが必要になるのは,
・dynamic_castを必要とする場合
・ダウンキャストにおけるstatic_cast
・protected/private継承を無視するためのC-likeキャスト
くらいだと思います。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました