代入の多重定義

C++パラメーターを 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' を許可しません。

関連参照

IBM Copyright 2003