HOWTO · C++

C++ で==演算子をオーバーロードする

これは、C++ での==演算子のオーバーロードを実装するためのプログラミングチュートリアルです。

この記事では、演算子のオーバーロードの基本について説明し、クラスでの == 演算子の簡単な実装を提供します。

C++ での演算子のオーバーロード

演算子のオーバーロードとは、クラスオブジェクトや構造体などのユーザー定義のデータ型とともに使用する場合に、演算子がどのように動作する必要があるかを変更することを指します。これらは、その演算子を使用するために呼び出されるクラスのメンバー関数のようなものです。

たとえば、Student のクラスがあり、どの学生のマークが他の学生よりも大きいかを確認したい場合、2つのオブジェクトの marks データメンバーを比較できる > 演​​算子をオーバーロードできます。結果を返します。

演算子のオーバーロードの構文は次のとおりです。

class className {
 public:
  returnType operator operatorSymbol([list of arguments]) {
    // definition
  }
};

operator は演算子のオーバーロードに使用されるキーワードであり、その後、オーバーロードする必要のある演算子の記号を指定することに注意してください。int、char、float などの基本的なデータ型の演算子をオーバーロードできないことに注意してください。

オーバーロードが許可されていない一部の演算子を除いて、ほとんどすべての演算子がオーバーロードされる可能性があります。これらの演算子は次のとおりです。

  • sizeof 演算子
  • typeid 演算子
  • スコープ解決 (::)
  • クラスメンバーアクセス演算子 (.(dot), .*(メンバー演算子へのポインター)
  • 条件演算子 (?:)

C++ で == 演算子をオーバーロードする

== は、比較演算子の分類に該当し、true または false のブール結果を返す equal to 演算子でもあります。演算子の左側と右側の 2つのオペランドが互いに等しいかどうかを判別します。

クラスのようなユーザー定義のデータ型の場合、この演算子をオーバーロードして、クラスの 2つのオブジェクトを比較し、2つのオブジェクトのすべてのデータメンバーが等しいかどうかを確認できます。

次のデータメンバーを持つクラス Employee について考えてみます。

class Employee {
 private:
  string name;
  int salary;
};

このクラスでは、== 演算子をオーバーロードして、2つの Employee オブジェクトが互いに等しいかどうかを確認できます。この関数は次のように実装できます。

bool operator==(const Employee &emp) {
  if (name == emp.name && salary == emp.salary) return true;
  return false;
}

これで、それらをすべてまとめて、完全なクラスを作成できます。

#include <iostream>
#include <string>
using namespace std;

class Employee {
 private:
  string name;
  int salary;

 public:
  Employee(string n, int s) {
    name = n;
    salary = s;
  }
  bool operator==(const Employee &emp) {
    if (name == emp.name && salary == emp.salary) return true;
    return false;
  }
};
int main() {
  Employee e1("David", 1000);
  Employee e2("David", 1000);
  if (e1 == e2)
    cout << "Equal" << endl;
  else
    cout << "Not Equal" << endl;
}

出力:

Equal

クラス階層の == 演算子をオーバーロードする

一部のクラスが親クラスで一部が子クラスであるなど、複数のクラスがある場合は、すべてのサブクラスとスーパークラスに演算子関数を実装する必要があります。たとえば、クラス A があり、== 演算子を実装した場合、このオーバーロードされた演算子は、そのすべてのサブクラスで使用できます。

class A {
 public:
  int foo;
  bool operator==(const A &a) { return foo == a.foo; }
};

これで、A のサブクラスである別のクラス B ができました。

class B : public A {
 public:
  int bar;
};

このクラスに == 演算子を実装しない場合、基本クラスの演算子関数が呼び出されますが、問題は、基本クラスがそれ自体のデータメンバーのみを比較し、B クラスのデータメンバを比較していないことです。したがって、子クラスにも演算子を実装する必要があります。

その実装の後、基本クラスの実装は、明示的に呼び出すまで呼び出されません。したがって、その関数を明示的に呼び出して、基本クラスのデータメンバーを比較します。

これは、以下のコードスニペットに示されています。

class B : public A {
 public:
  int bar;
  bool operator==(const B &b) {
    if (!A::operator==(static_cast<const A &>(b))) {
      return false;
    }
    return bar == b.bar;
  }
};

ドライバ関数は次のようになります。

int main() {
  B b;
  b.bar = 2;
  b.foo = 1;
  B b2;
  b2.bar = 2;
  b2.foo = 1;
  if (b == b2) {
    cout << "Equal" << endl;
  }
}

出力:

Equal