派生クラスのポインタの配列を関数に渡す – プログラミング – Home

派生クラスのポインタの配列を関数に渡す
 
通知
すべてクリア

[解決済] 派生クラスのポインタの配列を関数に渡す


お茶
 お茶
(@お茶)
ゲスト
結合: 21年前
投稿: 42
Topic starter  

継承は全てpublicとします。
基本クラスのポインタに派生クラスのポインタを代入できますが、
基本クラスのポインタの配列(vectorでもOK)を引数とする関数に
派生クラスのポインタの配列を渡したいのですがどうしたらよいのでしょうか?

class A{
};

class B : public A{
};

void f(A *ppA[])
{
}

int main()
{
B *pB[10];

f(pB); // <-これがエラー

return 0;
}

環境はWinXP + VC6です。
MFCは使ってません。(って見りゃわかりますね。)


引用未解決
トピックタグ
REE
 REE
(@REE)
ゲスト
結合: 24年前
投稿: 240
 

直接渡すことは出来ません。(少なくとも保障されません)
事前に変換する必要があります。


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

REE さんの回答で完璧なのですが補足など。

pB は &pB[0] つまり B** 型です。 ppA は A** 型です。
B** から A** へ暗黙に型変換するコンテキストは無いわけです。
(B* から A* へ暗黙に型変換するコンテキストはあるが、上記の変換は無い)

この場合、渡したいのは配列の中身の B* が A* になって欲しい、のでしょう。
ということは配列の中身を1つづつ変換しなければなりません。

似てるけど違うバグ(もっとエグイ:コンパイルエラーにならない)を、
ウチの pc-lint は検出するぜい!と gimpel 社が CM してるページなどを
紹介してみたりして。
http://www.gimpel.com/html/oldbugs/bug1552.htm

http://www.gimpel.com/html/bugs.htm
回答を見ずに全部正解できたらなかなかのものです。


返信引用
お茶
 お茶
(@お茶)
ゲスト
結合: 21年前
投稿: 42
Topic starter  

おふたりともありがとうございます。

さらに質問したいのですが、B**をA**に強引にキャストしてはいけないのでしょうか?

例えば上の例だと

f((A **)pB);

とすればコンパイルは可能です。
ポインタは全て同じサイズだと思いますのでこれでもOKな気がするのですが。

vector<B *>をvector<A *>にしたい場合はお答え通りに変換したvectorを作ればいい
ようですね。


返信引用
REE
 REE
(@REE)
ゲスト
結合: 24年前
投稿: 240
 

なぜ駄目かと言うと、B* から A* への変換で、指す先が変わることがありえるのです。

ポインタのサイズが同じで、単一継承しかしていなければ、大丈夫かもしれません。
しかし、少なくとも保障されていません。


返信引用
お茶
 お茶
(@お茶)
ゲスト
結合: 21年前
投稿: 42
Topic starter  

ありがとうございます。

> なぜ駄目かと言うと、B* から A* への変換で、指す先が変わることがありえるのす。

なるほど、確かに多重継承した場合なんかそうですね。
保障されていないというのもうなずけます。
安全性を考えると上の例のような強引なキャストは避けたほうがいいですね。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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