- ベストアンサー
仮想関数でのオーバーライドでの質問
- 仮想関数でのオーバーライドでの質問。二つの派生クラスを定義したが、一つ目のクラスのメソッドが実行されないことに困っている。
- 一つ目のクラスのメソッドが実行されない原因について教えてほしい。
- 実行結果が予想と異なり、一つ目のクラスのメソッドが表示されない問題について質問しています。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
以下、No2の要求に対する簡単な例を挙げます。 #include <iostream> using namespace std; //**************************** // //**************************** class Var { private: public: virtual void func() { cout << "message00" << "moji" << endl; } }; //**************************** // //**************************** class Msg01 : public Var { private: public: void func() { cout << "message01" << "moji" << endl; } }; //**************************** // //**************************** class Msg02 : public Var { private: public: void func() { cout << "message02" << "moji" << endl; } }; //**************************** // //**************************** int main() { Msg01 val; Msg02 msva; Var *base[2]; base[0] = &val; base[1] = &msva; base[0]->func(); base[1]->func(); getchar(); return 0; }
その他の回答 (4)
- Tacosan
- ベストアンサー率23% (3656/15482)
関数を static で宣言すると「オブジェクトの情報」は完全に消えますから, static な関数から非static な関数を呼び出すためには消えてしまった「オブジェクトの情報」を static な関数に何らかの形で渡す必要があります. ですから, func を基底クラスに static にしたままで「val.func() から Msg01::show() を呼んでほしい」とか「msva.func() から Msg02::show() を呼んでほしい」というのは本質的にかなり無理があります. func に「実際のオブジェクト」を渡すくらいしかないんじゃないかなぁ. ちなみに普通「Msg02 を宣言する」といったら class Msg02; だけだし, 拡大解釈しても class Msg02 : public Var { ... }; までだから, これ*だけ*で「Msg01::show を呼ばなくなる」ということはないです. Msg02 のコンストラクタを呼ばなければいい....
お礼
早速の回答ありがとうございます。 ウィンドウプロシージャだと静的プロシージャから動的にもってかないと派生クラスを生かせないので こういった質問をしました。 Taconsan氏の仰る通りだと、ウィンドウプロシージャをクラスに内包して使うのは危険なんでしょうかねぇ。
- Tacosan
- ベストアンサー率23% (3656/15482)
Var::func を static にしない.
お礼
回答ありがとうございます。 実はWinAPIのプロシージャのクラス化をして継承可能にしようとしている最中なんです。 それでどうしても静的にしなければならないのでこういうプログラムを書いています。
補足
どうしても静的関数から呼び出したいのです。
- buriburi3
- ベストアンサー率44% (353/792)
Var* Var::re = NULL; がグローバル宣言になってるから一個しか存在しない。 Msg01 val; を実行した時点では Var::re は val だけど Msg02 msva; を実行した時点で Var::re は msva に書き換えられてる。 なので val.func(); では msva->show( ) がコールされる。
お礼
ご指摘ありがとうございます。 ずっとこれで煮詰まってたんで、回答が欲しかったです。
補足
このソースの実行結果が正常に message01moji message02moji にするにはどうしたらいいんでしょうか? ここでも対策できず詰んでしまっています。 二重に質問してしまうのかも知れませんが、もしよろしければお願いします。
- Tacosan
- ベストアンサー率23% (3656/15482)
「Msg02を宣言したため」が何を意味するのかよくわからんのだけど, Msg02 msva; で Var::Var() が実行されている.
補足
「Msg02を宣言したため」というのは、Msg02を宣言したからMsg01のshow()が呼ばれなくなったのではないか?と考えていたからです。実際注釈して無効にしてたら実行結果が変わったんで。 なのでMsg02の宣言がMsg01に影響をもたらしていると考えていたのですが、何故かはわかりませんでした。
お礼
回答ありがとうございます。 配列として管理すればちゃんとできるんですね。 このやり方でWIndowsプロシージャの継承をやってみようと思います。