(続)クラスの継承について

[戻る]
Fortran使い 2005/08/09(火) 12:13:05
前回の続きです。今度はVC++(MFC)に特化した話(経験のある人なら常識かもしれませ
んが)だと思います。勉強中ですがよろしくお願いします。

アプリケーションウィザードで作成されたviewクラス(CMDItestView)ここから派生させ
たクラスCGraphInputViewがあります。

それぞれのOnDraw関数には
pDC->TextOut(0,0,"IN CMDItestView");
pDC->TextOut(0,0,"IN CGraphInputView");
とありどちらが実行されたかわかるようにしました。
DocumentTemplateでCGraphInputViewに関連付けて実行しても
IN CMDItestViewが表示されます。
オーバーライドされているはずなのになぜこのようになるのでしょうか?(質問1)

とりあえず「ゼロからはじめるC++」を参考にして
関数の定義のところで
virtual void OnDraw(CDC* pDC) = 0;
(なんとなくわかるのですがなんと言う文法なのでしょうか?(質問2))
Ondrawの処理の内容をコメントアウトして消してしまえば
IN CGraphInputViewと表示されますがオーバーライドがメンバ関数の性質
を変更するものならば派生元のクラスのOnDrawを変更するのは変な話では
ないでしょうか?(質問3)

それから、ダイナミックにインスタンスを生成するという部分の
DECLARE_DYNCREATE
IMPLEMENT_DYNCREATE
のセットも派生元でキャンセルして派生クラスに設定しなければならないのはなぜなの
でしょうか?(質問4)
何もしなければそのまま継承されてもいいような気もするのですが。

そのほかにもメッセージマップなどもありますが(今回は気にしてませんが)
継承する上で気をつけるべきところなどございましたらアドバイスよろしくお願いしま
す。

KING・王 2005/08/09(火) 12:42:53
MFC関係はあまり詳しくないのではずしていたらごめんなさい。

○質問1(3)について
両方呼ばれて、上書きされているなんてことはありませんか?

○質問2について
純粋仮想関数でよかったと思います。

とりあえず、先の質問の回答でPATIOも指摘されているように、
MFC云々以前に、C++の基本的な文法事項を勉強すべきだと思います。

Fortran使い 2005/08/09(火) 13:30:33
少し訂正です。質問1、質問3は間違いでした。Ondraw関数のオーバーライドについて
はやり直してみたところきちんとオーバーライドされていました。DECLARE_DYNCREATEの
ところの変更がされていなかったための誤作動だったと思います。

それから、質問2の意図としては関数に0を代入して無効化しているところです。
関数名というのは関数のエントリーポイント(ポインタ?)を表しているとの表現
を見たことがありますがこれはどういう処理なのでしょうか。私の手持ちの文献には
ここの記述がありませんでしたので。

質問4は意図としては間違っていないと思います。性質を変更しなくてもいものも
あえてオーバーライド(これはオーバーライドではないような気もしますが。)してい
るように見えます。ここに関しては誤作動というよりはこの処理をしないとコンパイル
自体が通りません。

あと、誤解があるかもしれないので一応説明させていただきますと一応C++の方も
勉強しています。文献当たって、試行錯誤して自分ではどうしようないと思ったときに
登校させていただいているつもりです。もちろん、C++の知識自体も身につくよう努力は
欠かしておらず「勉強中」なのです。ということで温かく見守っていただけると幸いで
す。もしかしたら私のレベルだと場違いだというのであれば他に探してみようかとも思
います。

tetrapod 2005/08/09(火) 13:50:18
virtual T vfunc()=0; という記述は単に形式的なもので、
関数を0に初期化しているわけではありません。
で、まっとうな C++ の教科書なら必ず記述があるはずですが、ない?
# そんな本捨てちゃえ...
MFC の入門書/教科書には「そんなこと知っててあたりまえ」の前提のもと、
わざわざ記述していないかもしれません。
MFC を使う上では C++ の知識が要求されます。

Web での説明なら、たとえば
http://www5c.biglobe.ne.jp/~ecb/cpp/06_08.html

arr 2005/08/09(火) 14:39:21
>質問4は意図としては間違っていないと思います。性質を変更しなくてもいものも
>あえてオーバーライド(これはオーバーライドではないような気もしますが。)してい
>るように見えます。ここに関しては誤作動というよりはこの処理をしないとコンパイル
>自体が通りません。

コンパイルが通らないって...
マクロに渡すパラメータを間違えてるとか、記述方法にどこか問題は無いでしょうか。
質問1、3についてもそうなんだけど、投稿前のチェック(自分が間違ったことをしてな
いかの確認)が少々足りないような気がしますけど。

arr 2005/08/09(火) 15:08:17
> 性質を変更しなくてもいものも

派生元クラスの CreateObject と派生先クラスの CreateObject が同じでいいはずが無い。
"派生先クラス.CreateObject()" の実体が "new 派生元" ではまずい。
だから、IMPLEMENT_DYNCREATE の性質は派生元と派生先で明らかに違うと思う。

Fortran使い 2005/08/09(火) 15:19:36
[[解決]]
皆さん、ありがとうございました。
一通り情報は得られましたので勝手ながら「解決」
ということにさせていただきます。
もう一度勉強しなおしてから出直してきます。

arr 2005/08/09(火) 15:44:36
原因についてあまり触れないまま「解決」にしてますが、
質問1、2、4はどれも派生先クラスで、
   IMPLEMENT_DYNCREATE(派生元クラス, CView)
などと、派生元の記述をそのままコピペしてしまったせいかしら?
いかにもそういう香りが。(^^;

arr 2005/08/09(火) 15:52:18
>質問1、2、4はどれも派生先クラスで、
質問1、3、4 ね。

Fortran使い 2005/08/09(火) 17:29:49
C++を理解していればわかる問題というご意見が多かったので原因は書かなくてもよいの
かなという空気になっていたので解決としてしまいましたが、一応礼儀のうちというこ
とで追記しておきます。

はじめに断っておきますと、最初の発言でもお分かりの通りこれを投稿して時点では「動
かない」という状況ではなく自分で試行錯誤して正常に動くとこまで言ったのですがそ
の間のプロセスが考え方としてしっくりこないという内容でした。

ですからarrさんの2つ上の発言のようなミスではありません。あえて言えばarrさんの
さらに上の発言の内容が一番聞きたかった内容です。さらにひとつ上の発言に関しては
自分で動かせるところまで言ってからの投稿なので該当しないとは思います。

同様の内容でメッセージマップなど普通のクラスにおける継承で関数のオーバーライド
と異なるような扱い(つつかれるとぼろが出ると思いますが)の部分をアドバイスいた
だきたいと思っていたところです。質問1、3に関しては勘違いですのであまり触れな
いでいただきたいと思います。

もちろん理解不足だとは思います。ただ、それを補うための掲示板であることだけはわ
かってください。

arr 2005/08/09(火) 18:15:29
>ですからarrさんの2つ上の発言のようなミスではありません。あえて言えばarrさんの
>さらに上の発言の内容が一番聞きたかった内容です。さらにひとつ上の発言に関しては
>自分で動かせるところまで言ってからの投稿なので該当しないとは思います。

該当しない?ということは、

>それから、ダイナミックにインスタンスを生成するという部分の
>DECLARE_DYNCREATE
>IMPLEMENT_DYNCREATE
>のセットも派生元でキャンセルして派生クラスに設定しなければならないのはなぜなの

まだ派生元でキャンセルしないといけない状況なのですか?
キャンセルとは派生元のそのマクロをコメントアウトする、とかいう意味でしょうか。
そうしないとコンパイルが通らないの?

自分はそんな目にあったことがなくキャンセルなどしなくてもちゃんとできているので、
どういう場合にそういうことになるのか、気になるのです。
常にキャンセルしなければならないと思い込んでいるならそれは間違いですし。

個人的に気になるというだけなので、聞きたいこと以外についてはあまり詮索されたくな
い、というなら放置していただいてもかまいません。

arr 2005/08/09(火) 18:47:16
>virtual void OnDraw(CDC* pDC) = 0;
これのせいかな。それなら納得。
仮想クラスに変更したら IMPLEMENT_DYNCREATE とは矛盾するでしょうね。

fortran使い 2005/08/09(火) 18:48:52
arrさん、ご意見ありがとうございます。
何か攻められているような気がしたのでご期待の添えない
回答になったのかもしれませんが、今後もこの板を気持ちよく使いたいので
お答えします。揚げ足取りのような形にもしたくありませんので私の経験したことを
時系列で簡潔に記入していきます。

1.aprwizardでできたviewクラスの派生クラスを作成。

2.ドキュメントテンプレートに関連付けたところマクロ記述のところが原因で
コンパイルできないとのエラー。

3.派生元のマクロを削除、派生先にマクロを追加で問題解決。

2、3のあたりやっているところで継承=機能の引継ぎということにそぐわないのでは
という疑問(マクロをメンバ関数の一部のように考えていたため)

OnDrawの件はここら辺のこととごっちゃにしたためでもともと問題は発生していなかっ
たということです。

マクロのコメントアウトですが正直コメントアウトしないでできるというのは有益な情
報です。ためさせていただきます。(端末を変えたので今すぐはできません。)

派生元のマクロをコメントアウトしたのは「ゼロからはじめるVC++」でそうしていたか
らで、そういう作法であると思ってしまったからです。

できる人から見れば丸頼りに見えるかもしれませんが大目に見てください。
中にはマルチさんやアルゴリズム考えてなどとの投稿も結構目に付きますので。

fortran使い 2005/08/09(火) 18:52:29
純粋仮想関数とマクロが影響しているということですか。
ありがとうございます。
いろいろためさせていただこうと思います。

とおりすがり 2005/08/09(火) 23:09:25
>中にはマルチさんやアルゴリズム考えてなどとの投稿も結構目に付きますので。

意味不明…
↑があるのだから、自分のことには目をつむれとでも言ってるのでしょうか??
↑をやったら、注意されるだけで、実際まともな回答はもらえてないでしょうに。

じゃんぬねっと [HomePage] 2005/08/10(水) 18:30:29
> できる人から見れば丸頼りに見えるかもしれませんが大目に見てください。

フレーム覚悟で言います。
最小限の検証をやった上で言っていますか?

掲示板はサポートセンタではありません。

KING・王 2005/08/11(木) 07:59:44
>中にはマルチさんやアルゴリズム考えてなどとの投稿も結構目に付きますので。

これは、
「世の中には大量殺人を犯す人もいるのだから、私がした強盗ぐらいは許してください」
というのと、ほとんど同レベルの発言という気がしますが・・・

KING・王 2005/08/11(木) 08:06:58
申し訳ございません。

読み返してみると、先の私の発言は、すこし厳しすぎるような気がしました。
できれば、みなさま無視して下さい。

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