2011-01-04 18 views
9

スーパークラスの関数のオーバーロードを防ぐ何かがC++標準にありますか?スーパークラスの関数のオーバーロード

クラスのこのペアを皮切り:私は簡単にB::foo()を呼び出すことができます

class A {   // super class 
    int x; 

public: 
    void foo (int y) {x = y;} // original definition 
}; 

class B : public A { // derived class 
    int x2; 

public: 
    void foo (int y, int z) {x2 = y + z;} // overloaded 
}; 

B b; 
    b.foo (1, 2); // [1] 

をしかし、私はA::foo()を呼び出そうと...

B b; 
    b.foo (12); // [2] 

..コンパイラエラーが発生する:

過負荷がないように210
test.cpp: In function 'void bar()': 
test.cpp:18: error: no matching function for call to 'B::foo(int)' 
test.cpp:12: note: candidates are: void B::foo(int, int) 

はちょうど私が何かが欠けていなかったことを確認するために、私はBの関数の名前を変更:

class B : public A { 
    int x2; 

public: 
    void stuff (int y, int z) {x2 = y + z;} // unique name 
}; 

そして今、私は2番目の例を使用してA::foo()を呼び出すことができます。

この規格はありますか?私はg ++を使用しています。

答えて

17

あなたは、クラスBの定義内で使用して宣言を使用する必要があります使用して宣言なし

class B : public A { 
public: 
    using A::foo;   // allow A::foo to be found 
    void foo(int, int); 
    // etc. 
}; 

、コンパイラが同じで他のエンティティのためのベースクラスを検索しません効果的に名のルックアップ中にB::fooを見つけて、名前のため、A::fooが見つかりません。

+1

は元のメンバ関数を "非表示にする"。 –

+6

+1 - Scott MeyersのEffective C++でこれがカバーされていることに注意してください。Item 33:継承された名前を隠すことは避けてください。 –

0

A::foo(int)の実装をオーバーライドしていない代わりに、A::fooのエイリアシングを行い、(int、int)の代わりにそのシグニチャを変更しています。 James McNellisが述べたように、using A::foo;宣言は、Aからの関数を利用可能にします。

+0

OPは「オーバーライド」とは言わず、オーバーロードとオーバーロードは彼がやっていることです。オーバーライドは仮想関数に適用されます。 –

+0

彼がしていたことは、過負荷だったのです。彼が代わりにしたのは、オーバーライドに似たものでしたが、元の方法をエイリアシングするという追加のボーナスがありました。 James McNellisが指摘したように、usingステートメントは問題を解決し、オーバーロードを可能にします。 –

関連する問題