引数が異なる関数を派生クラスで定義する

[戻る]
お茶 2005/07/06(水) 17:39:40
まずは以下のコードを見てください。

#include <iostream>

class A {
public:
    virtual void f() {}
};

class B : public A {
public:
//  virtual void f() { A::f(); } このコメントを外せばOKなのですが・・・
    virtual void f(int a) = 0;
};

class C : public B {
public:
    virtual void f() { std::cout << "f()" << std::endl; }
    virtual void f(int i) { std::cout << "f(int)" << std::endl; }
};

int main()
{
    B *pB = new C;
    pB->f();

    return 0;
}

上のコード、pB->f()で引数が足らないとコンパイル時にエラーが出ます。
でもBの基本クラスであるAに、ちゃんとf()は存在しています。
コメントを外せばコンパイル可能なのですが、何か釈然としません。
これがエラーになるはC++の仕様なのでしょうか?

環境はVC++6.0SP6 WinXPSp2 MFC未使用です。

YuO [E-Mail] 2005/07/06(水) 18:19:28
基底クラスと派生クラスで同一の名前の関数があった場合,
基底クラスの関数は隠されます。
# 引数は考慮されない。
これはC++の仕様です。

usingを使う,というのが基本的な解決策です。

お茶 2005/07/07(木) 12:22:04
[[解決]]
ありがとうございます。
仕様ですのでこれはこういうものだ、と納得するしかないですね。

けど、ちょっと感覚的に違和感があります。
BはAを知っているわけですから、当然f()も呼べていいような気がします。
なんでこんな仕様になったのでしょうか?

D&Eにこの辺のことが書いてあるのでしょうか?
今度読んでみることにします。

dairygoods 2005/07/07(木) 16:08:34
> BはAを知っているわけですから、当然f()も呼べていいような気がします。
> なんでこんな仕様になったのでしょうか?

BはAを知らないかもしれない、という思想の方が強かったのだと思います。
で、知っていることを明示するには using を使いなさいと。

#Javaの場合は、隠されませんね。

お茶 2005/07/07(木) 17:21:01
> BはAを知らないかもしれない、という思想の方が強かったのだと思います。
> で、知っていることを明示するには using を使いなさいと。

なるほど、確かにそういう考えもありますね。

あと、もしB::f(int)にデフォルト引数があった場合、f()が隠されないと逆にまずい
ですね。
まあ、そんな設計しないでしょうが・・・

参考になりました、ありがとうございます。

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