Blueさん、わかりやすい回答ありがとうございます。
ようやくBlueさんの言いたいことが理解できました(^o^)
ちなみにクラスCDropComboBoxに自作のメンバ関数AddStringを追加する場合、
この名前じゃまずいですよね?
CDropComboBoxはCComboBoxの派生クラスなのでCComboBoxのメンバ関数と同じ関数名はま
ずいのでは?
>CSelLogFile dlg;
>dlg.m_DropCmb1_Ctrl.AddString
>
>こうすると、CSelLogFileのメンバ変数を参照できるはずですけど。
>dlgはCSelLogFile クラスのthisポインタと同じ働きになると認識しています。
>実際、このやり方で他クラスのメンバ変数に値を代入したりリードしたりしたことがあ
>るのですが!?
それなら、試してみてください。
多分実行中に、ASSERTで落ちるでしょうが・・
CSelLogFile dlg;
この書き方をするのは、通常は新しくこのダイアログを開く時です。
これが既に開いているダイアログを指すことはありません。(Attach時を除く)
確かに、CSelLogFileのメンバ変数を参照出来ますが、
それは、別の“インスタンス”のメンバ変数です。
>ちなみにクラスCDropComboBoxに自作のメンバ関数AddStringを追加する場合、
>この名前じゃまずいですよね?
>CDropComboBoxはCComboBoxの派生クラスなのでCComboBoxのメンバ関数と同じ関数名はま
>ずいのでは?
特に問題ありません。オーバーライドしているだけです。
REEさん、すいません。
ダメでした。落ちました。
このやり方だとコントロールの場合は無理みたいです。
int型などの値のリードライトはできるけど・・・
>>ちなみにクラスCDropComboBoxに自作のメンバ関数AddStringを追加する場合、
>>この名前じゃまずいですよね?
>>CDropComboBoxはCComboBoxの派生クラスなのでCComboBoxのメンバ関数と同じ関数名は
>>まずいのでは?
>特に問題ありません。オーバーライドしているだけです。
どっちの関数がコールされてるかどう区別されるのですか?
> どっちの関数がコールされてるかどう区別されるのですか?
CDropComboBoxのAddStringはあらたにつくったほうが呼ばれます。
というか、区別してつかう必要はないと思ったのでオーバーライドしているんですが。
# CDropComboBox::AddStringでは、CComboBox::AddStringを呼びたいのでキャストして
いますのがわかると思います。
詳しくは「オーバーライド」で、Google検索してください。
MFC関係なく、C++の基本的なことです。
>int型などの値のリードライトはできる
確かに出来ますが、これは元のクラスとは別の変数です。
int i=3;があるときに
新たに int j; j++; としてもiの値は変化しませんよね?
それと同じことです。
CSelLogFile dlg;
dlg.m_i++;
としても上のjと同じで、
既に開いているダイアログのメンバ変数m_iには影響を与えません。
>>特に問題ありません。オーバーライドしているだけです。
>どっちの関数がコールされてるかどう区別されるのですか?
オーバーライドについて、調べた上での質問でしょうか?
CDropComboBox型でAddStringを呼べば新しいほうが呼ばれます。
CComboBox型でAddStringを呼べば元のほうが呼ばれます。
ちなみにこの辺はクラスの基本でもあるので、一度勉強しなおすといいでしょう。
>オーバーライドについて、調べた上での質問でしょうか?
>CDropComboBox型でAddStringを呼べば新しいほうが呼ばれます。
>CComboBox型でAddStringを呼べば元のほうが呼ばれます。
これって「オーバーロード」の説明では?
って気になって見てみたらAddStringの宣言にはvirtualがついてないので
確かに「オーバーライド」ではないようです。
オーバーロードって、引数や戻り値がちがう同名の関数だと思っていたんですが違うの
でしょうか?
オーバーロードとは
http://e-words.jp/w/E382AAE383BCE38390E383BCE383ADE383BCE38389.html
>既に開いているダイアログのメンバ変数m_iには影響を与えません。
ようするにこの処理はダイアログを開く前や、閉じた後に
別のクラスから行う処理。ということですよね?
ダイアログが開かれている場合は変数の変更はできないということですか。
なんかクラスの概念が全然理解で規定ないようですけど。
class Foo
{
public:
m_i;
Foo() : m_i( 0 ){}
void CountUp(){
m_i++; // 自分自身(this)のm_iをカウントアップ
}
};
int main()
{
Foo f;
// fのm_iをカウントアップ
f.m_i++;
// f.CountUp(); と同じなのは理解できますか?
// fの関数CountUpを呼び出す。CountUp関数のなかのthisはfのポインタ。
return 0;
}
>// f.CountUp(); と同じなのは理解できますか?
>// fの関数CountUpを呼び出す。CountUp関数のなかのthisはfのポインタ。
これは理解できますよ。
では、上の Foo を使って、
class Bar
{
public:
Foo* m_f; // ポインタとするのはなぜ?
void Test1()
{
m_f->CountUp();
}
void Test2(
{
Foo f;
f.CountUp(); // ここでカウントアップした f はどうなる?
}
};
int main()
{
Foo f;
Bar b;
b.m_Foo = &f;
b.Test1();
// b.Test2(); とどうちかう?
return 0;
}
>オーバーロードって、引数や戻り値がちがう同名の関数だと思っていたんですが違うの
>でしょうか?
>
>オーバーロードとは
> http://e-words.jp/w/E382AAE383BCE38390E383BCE383ADE383BCE38389.html
今回の場合、オーバーロードというのが適切かどうかはわかりませんが、
CDropComboBox::AddStringが、CComboBox::AddStringの実装を
隠してしまっています。
オーバーライドであれば、たとえ基底クラスへキャストされたとしても
常に新しい方の実装が呼ばれます。
virutalな関数じゃないとオーバーライドとは呼ばないのですね。
間違えて覚えていたようです。
オーバーライドについてWebで調べなおしてみたら、
基本クラスの関数が仮想になっているものだけをオーバーライドとする説明と
基本クラスの関数が仮想じゃなくてもオーバーライドとする説明が混在していました。
どちらが正しいのかはよく分かりませんが、
個人的には、後者の理解でした。(そしておそらくBlueさんも)