演算子オーバーロードの基本概念
演算子オーバーロードとは、組み込み型に対して定義されている演算子を、ユーザ定義型に対しても適用可能にする仕組みです。これにより、クラスオブジェクトに対して直感的な算術記法を使用できます。
一般的な形式は以下の通りです:
戻り値の型 operator 演算子記号 (引数リスト)
単項演算子のオーバーロード
前置インクリメント演算子の実装
前置++演算子をオーバーロードする例です。メンバ変数を直接変更し、変更後のオブジェクトを返します。
class Counter {
public:
int value;
Counter(int init) : value(init) {}
Counter operator++() {
++value;
return Counter(value);
}
};
int main() {
Counter c(5);
++c;
std::cout << c.value; // 出力: 6
return 0;
}
符号反転演算子の実装
単項マイナス演算子をオーバーロードし、新しいオブジェクトを生成して返します。
class SignedValue {
public:
int data;
explicit SignedValue(int v) : data(v) {}
SignedValue operator-() const {
return SignedValue(-data);
}
};
int main() {
SignedValue sv(7);
SignedValue neg = -sv;
std::cout << neg.data; // 出力: -7
return 0;
}
二項演算子のオーバーロード
加算演算子をオーバーロードして、同じクラスのインスタンス同士の足し算を可能にします。
class Point {
public:
int x;
Point(int coord) : x(coord) {}
Point operator+(const Point& other) const {
return Point(x + other.x);
}
};
int main() {
Point p1(10), p2(20);
Point sum = p1 + p2;
std::cout << sum.x; // 出力: 30
return 0;
}
比較演算子のオーバーロード
構造体に対して大小関係を定義します。structでもclassと同様に演算子オーバーロードが可能です。
struct Score {
int points;
bool operator<(const Score& rhs) const {
return points < rhs.points;
}
};
入出力ストリーム演算子のオーバーロード
istreamおよびostreamとの連携を実現します。friend宣言により、プライベートメンバへのアクセスを許可します。
class Record {
public:
int id;
int score;
friend std::ostream& operator<<(std::ostream& out, const Record& r) {
out << r.id << " " << r.score;
return out;
}
friend std::istream& operator>>(std::istream& in, Record& r) {
in >> r.id >> r.score;
return in;
}
};
int main() {
Record rec;
std::cin >> rec;
std::cout << rec;
return 0;
}
代入演算子のオーバーロード
オブジェクト間の深いコピーを制御します。自己代入のチェックや動的メモリ管理が必要な場合は、より堅牢な実装が求められます。
class Vector2D {
public:
int u, v;
Vector2D(int x, int y) : u(x), v(y) {}
Vector2D& operator=(const Vector2D& src) {
if (this != &src) {
u = src.u;
v = src.v;
}
return *this;
}
};
int main() {
Vector2D vecA(1, 2), vecB(3, 4);
vecA = vecB;
std::cout << vecA.u << " " << vecA.v; // 出力: 3 4
return 0;
}
添字演算子のオーバーロード
配列のようなインターフェースを提供します。境界チェックや読み取り専用アクセスの実装も検討すべきです。
class Buffer {
public:
int x, y;
int storage[100];
Buffer(int initX, int initY) : x(initX), y(initY) {}
int& operator[](size_t idx) {
return storage[idx];
}
const int& operator[](size_t idx) const {
return storage[idx];
}
};
int main() {
Buffer buf(0, 0);
buf[50] = 999;
std::cout << buf[50]; // 出力: 999
return 0;
}