2つのビューの処理

[戻る]
hanabi 2003/12/04(木) 14:58:18
いつもお世話になっています。

少し前に「ドキュメントテンプレートについてhttp://rararahp.cool.ne.jp/cgi-
bin/lng/vc/vclng.cgi?print+200311/03110063.txt 」
という質問をさせていただいたのですが、追加で質問させてください。

ここでは元々存在したメインフレームを「メインフレーム」、新しく作成したフレームを
「サブフレーム」と呼ぶことにします。
前回の質問で答えていただいてフレームを2つ表示することができるようにはなったので
すが、サブフレームの描画処理について悩んでいます。
基本的には2つのフレームで同じような処理をと考えています。
同じ処理なら同じ内容のビューを作成すればできるのかなと思い、メインフレームに対応
しているビューの内容をコピーしてサブフレーム用のビューにペーストしてみたのです
が、全く同じソースを使用するのは見栄え的にも効率面でもあまりよくないと思い、
何かいい方法はないかと質問させていただいた次第です。

ちなみに全く同じソースをコピーしてみたら、メインフレームで行った描画が
そのままサブフレームに反映されてしまい、自分の意図したように動きませんでした。

ビューの内容をコピーする意外に、同じ動きをするビューを作成する方法はあるのでしょ
うか?
宜しくお願いします。

hanabi 2003/12/04(木) 14:59:32
失敗しました。
リンクはこれです。
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200311/03110063.txt

てつや 2003/12/04(木) 15:04:56
同じ動きをするなら基本となるVIEWを一つ作成し、メインVIEWとサブVIEWを派生させてみては
如何でしょうか?

hanabi 2003/12/05(金) 22:34:02
てつやさんご回答ありがとうございます。
返事が遅くなり申し訳ありませんでした。

すごく基本的なことなんですが、クラスを派生させた時のメリットとは何なのでしょうか?
自分的な考えとしては元となるクラスの関数や変数を使用できるという感じなのですが。
メインVIEWとサブVIEWで異なる表示をすることができるようになるのですかね?

まだクラスの派生について理解が浅いので少し調べてみます。
また、アドバイスなどありましたらよろしくお願いいたします。

てつや 2003/12/07(日) 04:09:46
すみません、あまり何が問題なのか理解できないまま投稿しています。
とりあえず、「ClsViewとClsView2の二つのViewがあり、同じ動きをさせたい部分があるが、
二つのクラスに同じ事を書くのは効率がわるいのでどうにかしたい」という問題ですよね。

それなら、以下のような構成にして
ClsViewとClsView2と同じ動きをさせたい場合、CBaseViewに書けば良いのでないでしょうか
というのが私の回答でした。

class CBaseView : public CView
{
};

class ClsView : public CBaseView
{
};

class ClsView2 : public CBaseView
{
};

hanabi 2003/12/09(火) 09:53:43
てつやさんありがとうございます。

確かに質問の意味がわかりませんね(^_^;
最初と最後で質問変わってるし… 申し訳ありません。

>「ClsViewとClsView2の二つのViewがあり、同じ動きをさせたい部分があるが、
>二つのクラスに同じ事を書くのは効率がわるいのでどうにかしたい」
そのとおりです。効率的なプログラムにしたいのです。

上に書いてくださっているのがクラスを派生しているのですよね?
このように定義した後で、CBaseViewにある関数をClsViewで必要としている場合、
ClsViewで再定義する必要はないのですか?

επιστημη [E-Mail] [HomePage] 2003/12/09(火) 10:57:21
> このように定義した後で、CBaseViewにある関数をClsViewで必要としている場合、
> ClsViewで再定義する必要はないのですか?

訊くまでもないでしょう。やってみればいい。

てつや 2003/12/09(火) 11:06:25
class CBase{
public:
   virtual void func1() { AfxMessageBox( "CBase::func1"); }
   virtual void func2() { AfxMessageBox( "CBase::func2"); }
           void func3() { AfxMessageBox( "CBase::func3"); }
};

class CHoge : public Base{
public:
   virtual void func2() { AfxMessageBox( "CHoge::func2"); }
           void func3() { AfxMessageBox( "CHoge::func3"); }
};

class CFoo : public Base
{
};

上記クラスを作り以下のコードを実行して動きを確認してみてください。
CBase base;
CHoge hoge;
CFoo  foo;

base.func1();
base.func2();
base.func3();

hoge.func1();
hoge.func2();
hoge.func3();

foo.func1();
foo.func2();
foo.func3();

*********************
func1はCHogeもCFooもオーバライドされていない為、
両方CBase::func1()が呼ばれるし
func2はCHogeのみオーバライドしている為、
CHogeはCHoge::func2()/CFooはCBase::func2()が呼ばれる

*********************
ついでにオーバライドする関数は仮想関数(virtual)でなければ、
ポリモーフィックなポインターの場合以下のような問題になります。
CBase* pBase;

pBase = &hoge;
pBase->func2();
pBase->func3();

派生先の実体(CHoge)を基底クラス(CBase)のポインターでさした場合、
func2()は仮想関数(virtual)宣言されている為、実体側(CHoge::func2()が正しく呼ばれる
func3()は仮想関数では無い為、実体が(CHoge)であろうとも、Choge::func3ではなく、
CBase::func3()が呼ばれる

てつや 2003/12/09(火) 11:09:01
リロードせず書き込みました。
>訊くまでもないでしょう。やってみればいい。
そうですね、小さいサンプル作ってやっていみるのが一番いいと思います。
人に聞いた事より、自分で苦労した事の方が覚えがいいですし理解も益します。

# 無駄レスですいません

hanabi 2003/12/09(火) 14:34:33
επιστημηさん もっともな意見です。すみません。
てつやさん ソースまで載せていただいてありがとうございます。

一応自分が今やっているものでクラスの継承をやってみたのですがうまくいかず、
新たにてつやさんの載せたとおりにやってみたのですが、やはり同じエラーがでました。
クラスの派生とは基本的には
>class CHoge : public Base{
のようにやるだけでいいんですよね?
いつもGetDocument()のあたりでエラーが出てしまうのですが…

エラーは
「"CBaseDoc"識別名を宣言するのに型が指定されていません。」
「"GetDocument"識別名を宣言するのに型が指定されていません。」
などです。

単純に書き方が間違っているのですか?
初歩的な質問ばかりで申し訳ないです。

επιστημη [E-Mail] [HomePage] 2003/12/09(火) 14:51:26
#include "BaseDoc.h" を忘れていませんか?

hanabi 2003/12/09(火) 15:21:50
επιστημηさん
忘れていました。初歩ですね。ごめんなさい。
これからやってみます。

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