C++言語における名前隠ぺいは、関数の場合引き数に関係なく名前の一致のみで発生するため、派生クラスの定義に基底クラスのメンバー関数のオーバーロードを記述すると、基底クラスの同名関数が見つからないコンパイルエラーが発生します。(「Effective C++第3版」33項、「C++の設計と進化」3.5.3項)
コンパイルエラーとなる派生クラスでのオーバーロード
派生クラスでメンバ関数をオーバーロード定義することによって名前が隠ぺいされてしまうサンプルを以下に示します。
class Base { public: virtual void mf(); ... }; class Derived : public Base { public: virtual void mf(int v); ... };
ごく普通の発想で、Baseクラスのメンバ関数mfの引数が異なるオーバーロード関数をDerivedで定義します。利用者に対するインタフェースを、利用者のカテゴリに応じて何段階かに分ける設計をするときがあります。
ここで、Derivedを呼び出すコードで、意図しないコンパイルエラーが発生します。
void useDerived() { Base* bas = new Derived; bas->mf(123); // OK bas->mf(); // OK Derived* der = new Derived; der->mf(123); // OK der->mf(); // コンパイルエラー }
GCCでのエラーは以下となります。
main.cpp:29: error: no matching function for call to ‘Derived::mf()’
Derivedクラスのオーバーロード定義を削除すると、Baseクラスのメンバ関数が可視になるので、mf()のコンパイルエラーはなくなります。