パラメーターを 1 つだけ持っている非静的メンバー関数を使用して、
代入演算子 operator= を多重定義します。
非メンバー関数である、多重定義された代入演算子を宣言することはできません。
次の例では、特定のクラスについて、代入演算子を多重定義する方法を示します。
struct X { int data; X& operator=(X& a) { return a; } X& operator=(int a) { data = a; return *this; } }; int main() { X x1, x2; x1 = x2; // call x1.operator=(x2) x1 = 5; // call x1.operator=(5) }
代入 x1 = x2 は、コピー代入演算子 X& X::operator=(X&) を呼び出します。代入 x1 = 5 は、コピー代入演算子 X& X::operator=(int) を呼び出します。 ユーザー自身があるクラスのコピー代入演算子を定義しない場合、コンパイラーがそれを暗黙的に宣言します。 したがって、派生クラスのコピー代入演算子 (operator=) が、その基底クラスの コピー代入演算子を隠蔽します。
ただし、コピー代入演算子はどれも、仮想として宣言できます。 次の例は、このことを示しています。
#include <iostream> using namespace std; struct A { A& operator=(char) { cout << "A& A::operator=(char)" << endl; return *this; } virtual A& operator=(const A&) { cout << "A& A::operator=(const A&)" << endl; return *this; } }; struct B : A { B& operator=(char) { cout << "B& B::operator=(char)" << endl; return *this; } virtual B& operator=(const A&) { cout << "B& B::operator=(const A&)" << endl; return *this; } }; struct C : B { }; int main() { B b1; B b2; A* ap1 = &b1; A* ap2 = &b1; *ap1 = 'z'; *ap2 = b2; C c1; // c1 = 'z'; }
次に、上記の例の出力を示します。
A& A::operator=(char) B& B::operator=(const A&)
代入 *ap1 = 'z' は、A& A::operator=(char) を呼び出します。 この演算子は virtual と宣言されていないので、コンパイラーは、 ポインター ap1 の型に基づいて関数を選択します。 代入 *ap2 = b2 は、B& B::operator=(const &A) を呼び出します。 この演算子は virtual と宣言されているので、コンパイラーは、 ポインター ap1 が指すオブジェクトの型に基づいて関数を選択します。 クラス C で宣言された、暗黙的に宣言されたコピー代入演算子は、 B& B::operator=(char) を隠蔽するので、 コンパイラーは、代入 c1 = 'z' を許可しません。
関連参照