重箱の隅@dynamic_cast

[戻る]
すずも 2004/04/11(日) 02:19:04
 一年以上もご無沙汰していました不義理者ですが、どうぞよろしくお願いします。

 仮想基本クラスから派生クラスへのキャストをするために、dynamic_castを使ってみ
たのですが、コンパイラに『ポリモーフィッククラスでないから駄目』って言われてし
まいました。
 ポリモーフィッククラスって仮想関数を含むクラスの事ですよね。どうしてそれを含
んでいないとdynamic_castが出来ないのでしょうか?

 そういうモノなのかも知れませんが、今一つ腑に落ちないので質問してみました。

n 2004/04/11(日) 09:56:22
仮想云々ではなくpublic継承かどうかでは。

class Base1{};
class Base2{};
class Base3{};
class Base4{};
class Base5{};
class Base6{};

class Derived :
 virtual public Base1, virtual protected Base2, virtual Base3,
 public Base4, protected Base5, private Base6 {};

void Foo()
{
    Derived* d;
    Base1* b1=dynamic_cast<Base1*>(d);//○
    Base2* b2=dynamic_cast<Base2*>(d);//×
    Base3* b3=dynamic_cast<Base3*>(d);//×
    Base4* b4=dynamic_cast<Base4*>(d);//○
    Base5* b5=dynamic_cast<Base5*>(d);//×
    Base6* b6=dynamic_cast<Base6*>(d);//×
}

YuO [E-Mail] 2004/04/11(日) 11:31:51
>  仮想基本クラスから派生クラスへのキャストをするために、dynamic_castを使ってみ
> たのですが、コンパイラに『ポリモーフィッククラスでないから駄目』って言われてし
> まいました。
>  ポリモーフィッククラスって仮想関数を含むクラスの事ですよね。どうしてそれを含
> んでいないとdynamic_castが出来ないのでしょうか?

派生クラス側から基底クラス側にキャストする場合を除いて,
そういう決まりになっているからです。


ちなみに,nさんが挙げているのは派生クラスから基底クラスの話なので,
static_castを使ったり,標準の変換を使ったりするのと条件は一緒です。

n 2004/04/11(日) 14:28:39
すずもさん、YuOさん、失礼しました。

すずも 2004/04/12(月) 02:36:12
 レスありがとうございます。

 確かにMSDNを見ても『出来ない』としか書いていなかったので、取りあえずは適当な
仮想関数を作って対処しています。それで一応は解決したのかも知れませんが…。

 それはそうと、さっき別のスレッドで紹介されていたεπιστημηさんの記事
(http://www.s34.co.jp/cpptechdoc/article/sizeof/)を見てきました。
 記事を自分なりに解釈してみた所、仮想関数を含むクラスと含まないクラスの実質的
な違いは仮想関数配列への関数ポインタを含むか含まないかっていう違いだけ、ってい
う結論にたどり着いた訳ですが、合っているんでしょうか?
 合っているとしたら、何故その程度の違いがdynamic_castにエラーを吐かせる程のも
のになり得るのか、ますます解せません。

 不毛な質問だとは思いますが、もう一度だけお願いします。

YuO [E-Mail] 2004/04/12(月) 07:14:23
>  記事を自分なりに解釈してみた所、仮想関数を含むクラスと含まないクラスの実質的
> な違いは仮想関数配列への関数ポインタを含むか含まないかっていう違いだけ、ってい
> う結論にたどり着いた訳ですが、合っているんでしょうか?

実装的な結論はそういうことです。
規格的にはv-tableを含む必要はないわけでして……。


>  合っているとしたら、何故その程度の違いがdynamic_castにエラーを吐かせる程のも
> のになり得るのか、ますます解せません。

v-tableにRTTIに必要な情報を潜り込ませていることが多いからです。
とりあえず,
VC++ではv-tableの先頭にRTTIに関する情報へのポインタを用意しています。

すずも 2004/04/15(木) 03:11:56
[[解決]]
 レス遅くなってしまいました。申し訳ないです。

 つまりこういう事でしょうか?
→dynamic_castをするのに必要なRTTIは、v-table内に仮想関数への関数ポインタ配列と
一緒に格納されている。v-tableは仮想関数を定義した時に定義される。v-table内に
RTTIを含む必然性は無いが、取りあえずそういう事になっている(JAVA辺りとの整合
性?)。

 どこまで合ってるのか不安ですが、一応は納得出来たので解決にチェック入れておき
ます。変な質問に付き合って下さって本当にありがとうございました。

επιστημη [E-Mail] [HomePage] 2004/04/15(木) 08:49:54
> v-table内にRTTIを含む必然性は無いが、取りあえずそういう事になっている

多くの処理系でそうやっているというだけのこと。
処理系依存であり、そのからくりについて規格書には何も触れられていません。

> (JAVA辺りとの整合性?)。

何の関係もありません。

古いスレッドには追加発言できません。