基底クラスと派生クラスからのメンバー関数の多重定義 (C++ のみ)

クラス Af と名付けられたメンバー関数は、 戻りの型や引数に関係なく、A の基底クラスで、 他の f という名前のメンバーをすべて隠します。 次の例は、このことを示しています。
struct A {
  void f() { }
};

struct B : A {
  void f(int) { }
};

int main() {
  B obj_B;
  obj_B.f(3);
//  obj_B.f();
}
コンパイラーは、void B::f(int) の宣言が A::f() を隠しているので、 関数呼び出し obj_B.f() を許可しません。
基底クラス A の関数を、派生クラス B で、 隠蔽ではなく多重定義するには、using 宣言を使用して、 関数の名前を B のスコープに導入します。 以下の例は、using 宣言 using A::f を除いては、直前の例と同じです。
struct A {
  void f() { }
};

struct B : A {
  using A::f;
  void f(int) { }
};

int main() {
  B obj_B;
  obj_B.f(3);
  obj_B.f();
}
クラス Busing 宣言があるので、 名前 f は 2 つの関数で多重定義されます。これで、コンパイラーは、関数呼び出し obj_B.f() を許可します。
関数 fusing 宣言を指定して、基底クラス A から派生クラス B に導入し、さらに A::f と同じパラメーター型を持つ B::f という名前の関数が存在するとします。 関数 B::f は、関数 A::f と競合するというより、むしろそれを隠します。次の例は、このことを示しています。
#include <iostream>
using namespace std;

struct A {
  void f() { }
  void f(int) { cout << "void A::f(int)" << endl; }
};

struct B : A {
  using A::f;
  void f(int) { cout << "void B::f(int)" << endl; }
};

int main() {
  B obj_B;
  obj_B.f(3);
}
上記の例の出力は、以下のとおりです
void B::f(int)
仮想関数を using 宣言を使用して多重定義できます。 次に例を示します。
#include <iostream>
using namespace std;

struct A {
  virtual void f() { cout << "void A::f()" << endl; }
  virtual void f(int) { cout << "void A::f(int)" << endl; }
};

struct B : A {
  using A::f;
  void f(int) { cout << "void B::f(int)" << endl; }
};

int main() {
  B obj_B;
  A* pa = &obj_B;
  pa->f(3);
  pa->f();
}
この例で、B::f(int) は仮想関数であり、using A::f; 宣言が指定されていても、A::f(int) をオーバーライドします。 この出力は以下のとおりです。
void B::f(int)
void A::f()