はじめまして、tekebonです。
VC++というよりもC++の質問になってしまいますがよろしくお願いします。
class CParent{
public:
int a;
void Set(int x){
a=x;
}
};
class CChild :public CParent{
public:
float b;
void Set(int x,float y){
a=x;
b=y;
}
};
こんな、クラスを作ったとします。
CChild obj;
obj.Set(3);
とすると、CChild::Set(int)がないように判断されてエラーになります。
この書き方はオーバーロードではなく、オーバーライドになってしまうのでしょうか?
CChild::Set(int)を記述すれば解決するのはわかりますが、文法的にどのような仕組みに
なっているのでしょうか?よろしくお願いします。<(_ _)>
> とすると、CChild::Set(int)がないように判断されてエラーになります。
> この書き方はオーバーロードではなく、オーバーライドになってしまうのでしょうか?
> CChild::Set(int)を記述すれば解決するのはわかりますが、文法的にどのような仕組みに
継承とはそう言うものです。(^^;)
派生クラスと基底クラスで同じメンバ名を使う場合には、
派生クラス内では派生クラスのメンバを使います。基底クラスのメンバに
アクセスする場合には大局演算子を使用しなければなりません。
P.S
オーバーロード、オーバーライド等の意味を今一度確認してみては。
>CChild::Set(int)を記述すれば解決するのはわかりますが、
重さんの言うとうり
obj.CChild::Set(3);
でも明示的に呼び出せます。
また、型キャストをすればオブジェクトの
基本クラスのメンバを安全で明示的に呼び出せます。
例の場合
obj.Set(3);を
CParent* lpObj = dynamic_cast<CParent>(&obj);
if(lpObj) lpObj->Set(3);
とすれば
obj.aは3になっています。
もちろん例の場合は、
CParent* lpObj = &obj;
lpObj->Set(3);
でもいけますが、設計によってはこれは、安全ではありません。
回答ありがとうございます
自分ではオーバーロードは、同じ関数名で異なるシグネチャーを
もつメンバ関数の作成だと思っています。
今回の例でいえばCParent::Set(int)というメンバ関数と
CParent::Set(float)というメンバ関数があればこれは
オーバーロードといえると思っています。
これに対し、オーバーライドは継承の時にまったく同じシグネチャー
のメンバ関数を上書きすることだと思っています。
ですからSet(int)に対して、Set(int,float)というメンバ関数は
オーバーライドではなく、オーバーロードのような関係になる
と思っていました。
実際にJavaで同じようなプログラムを作成してみたところエラーには
なりませんでした。
これはC++(VC++)でのルールということになるのでしょうか?
クラススコープ間で多重継承できないのはC++の仕様ですね
class CChild :public CParent{
public:
using CParent::Set;
float b;
~
とusing CParent::Set;を追加すれば期待通りの動作をするのではないですか?
多重定義だよね
失礼
ありがとうございました。
とりあえずの疑問は解決しました。