継承でオーバーロードするには?

[戻る]
tekebon 2001/02/09(金) 14:21:39
はじめまして、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)を記述すれば解決するのはわかりますが、文法的にどのような仕組みに
なっているのでしょうか?よろしくお願いします。<(_ _)>

2001/02/09(金) 16:21:20
> とすると、CChild::Set(int)がないように判断されてエラーになります。
> この書き方はオーバーロードではなく、オーバーライドになってしまうのでしょうか?
> CChild::Set(int)を記述すれば解決するのはわかりますが、文法的にどのような仕組みに

継承とはそう言うものです。(^^;)
派生クラスと基底クラスで同じメンバ名を使う場合には、
派生クラス内では派生クラスのメンバを使います。基底クラスのメンバに
アクセスする場合には大局演算子を使用しなければなりません。

P.S
オーバーロード、オーバーライド等の意味を今一度確認してみては。

ten_bun [E-Mail] 2001/02/09(金) 22:44:32
>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);
でもいけますが、設計によってはこれは、安全ではありません。

tekebon 2001/02/14(水) 11:55:33
回答ありがとうございます
自分ではオーバーロードは、同じ関数名で異なるシグネチャーを
もつメンバ関数の作成だと思っています。

今回の例でいえばCParent::Set(int)というメンバ関数と
CParent::Set(float)というメンバ関数があればこれは
オーバーロードといえると思っています。

これに対し、オーバーライドは継承の時にまったく同じシグネチャー
のメンバ関数を上書きすることだと思っています。

ですからSet(int)に対して、Set(int,float)というメンバ関数は
オーバーライドではなく、オーバーロードのような関係になる
と思っていました。

実際にJavaで同じようなプログラムを作成してみたところエラーには
なりませんでした。

これはC++(VC++)でのルールということになるのでしょうか?

ku 2001/02/14(水) 12:48:37
クラススコープ間で多重継承できないのはC++の仕様ですね

class CChild :public CParent{
public:
    using CParent::Set;
    float b;
    〜

とusing CParent::Set;を追加すれば期待通りの動作をするのではないですか?

ku 2001/02/14(水) 14:38:43
多重定義だよね
失礼

tekebon 2001/02/19(月) 09:46:17
[[解決]]
ありがとうございました。

とりあえずの疑問は解決しました。

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