C++ オーバーロード演算子とオーバーロード関数

C++ では、同じスコープ内の特定の関数と演算子に複数の定義を指定でき、それぞれ関数オーバーロードと演算子オーバーロード。

オーバーロード宣言とは、同じスコープ内で以前に宣言された関数またはメソッドと同じ名前を持つ宣言ですが、それらのパラメータリストと定義(実装)は異なります。

あなたが呼び出すとき、オーバーロード関数或オーバーロード演算子を呼び出すとき、コンパイラは使用するパラメータの型と定義内のパラメータの型を比較して、最適な定義を選択します。最適なオーバーロード関数またはオーバーロード演算子を選択するプロセスは、オーバーロード解決。

C++における関数オーバーロード

同じスコープ内で、機能が類似したいくつかの同名関数を宣言できますが、これらの同名関数の仮引数(パラメータの数、型、または順序を指します)は異なる必要があります。戻り値の型の違いだけで関数をオーバーロードすることはできません。

次の例では、同名の関数print()が異なるデータ型を出力するために使用されています:

例

#include <iostream> using namespace std; class printData { public: void print(int i) { cout << "整数は:" << i << endl; } void print(double f) { cout << "浮動小数点数は:" << f << endl; } void print(char c[]) { cout << "文字列は:" << c << endl; } }; int main(void) { printData pd; // 整数を出力 pd.print(5); // 浮動小数点数を出力 pd.print(500.263); // 文字列を出力 char c[] = "Hello C++"; pd.print(c); return 0; }

上記のコードがコンパイルおよび実行されると、次の結果が生成されます:

整数为: 5
浮点数为: 500.263
字符串为: Hello C++

C++における演算子オーバーロード

C++ に組み込まれているほとんどの演算子を再定義またはオーバーロードできます。これにより、カスタム型で演算子を使用できるようになります。

オーバーロードされた演算子は特別な名前を持つ関数であり、関数名はキーワード operator とその後にオーバーロードする演算子記号で構成されます。他の関数と同様に、オーバーロード演算子には戻り値の型とパラメータリストがあります。

Box operator+(const Box&);

加算演算子を宣言して、2つの Box オブジェクトを加算し、最終的な Box オブジェクトを返します。ほとんどのオーバーロード演算子は、通常の非メンバー関数として定義することも、クラスのメンバー関数として定義することもできます。上記の関数をクラスの非メンバー関数として定義する場合、各操作で2つのパラメータを渡す必要があります。次のようになります:

Box operator+(const Box&, const Box&);

次の例では、メンバー関数を使用して演算子オーバーロードの概念を示しています。ここでは、オブジェクトがパラメータとして渡され、オブジェクトの属性はthis演算子を使用してアクセスされます。次のようになります:

例

#include <iostream> using namespace std; class Box { public: double getVolume(void) { return length * breadth * height; } void setLength( double len ) { length = len; } void setBreadth( double bre ) { breadth = bre; } void setHeight( double hei ) { height = hei; } // + 演算子をオーバーロードして、2つの Box オブジェクトを加算する Box operator+(const Box& b) { Box box; box.length = this->length + b.length; box.breadth = this->breadth + b.breadth; box.height = this->height + b.height; return box; } private: double length; // 長さ double breadth; // 幅 double height; // 高さ }; // プログラムのメイン関数 int main( ) { Box Box1; // Box1 を宣言、型は Box Box Box2; // Box2 を宣言、型は Box Box Box3; // Box3 を宣言、型は Box double volume = 0.0; // 体積をこの変数に格納 // Box1 の詳細 Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0); // Box2 の詳細 Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0); // Box1 の体積 volume = Box1.getVolume(); cout << "Volume of Box1 : " << volume <<endl; // Box2 の体積 volume = Box2.getVolume(); cout << "Volume of Box2 : " << volume <<endl; // 2つのオブジェクトを加算して Box3 を取得 Box3 = Box1 + Box2; // Box3 の体積 volume = Box3.getVolume(); cout << "Volume of Box3 : " << volume <<endl; return 0; }

上記のコードがコンパイルおよび実行されると、次の結果が生成されます:

Volume of Box1 : 210
Volume of Box2 : 1560
Volume of Box3 : 5400

オーバーロード可能な演算子/オーバーロード不可能な演算子

以下はオーバーロード可能な演算子のリストです:

二項算術演算子 + (加算)、- (減算)、* (乗算)、/ (除算)、% (剰余)
関係演算子 == (等しい)、!= (等しくない)、< (小なり)、> (大なり)、<= (以下)、>= (以上)
論理演算子 || (論理OR)、&& (論理AND)、! (論理NOT)
単項演算子 + (正)、- (負)、* (ポインタ)、& (アドレス取得)
インクリメント・デクリメント演算子 ++ (インクリメント)、-- (デクリメント)
ビット演算子 | (ビットOR)、& (ビットAND)、~ (ビット反転)、^ (ビットXOR)、<< (左シフト)、>> (右シフト)
代入演算子 =, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>=
メモリの確保と解放 new, delete, new[ ] , delete[]
その他の演算子 ()(関数呼び出し)、->(メンバーアクセス)、,(カンマ)、[](添え字)

以下はオーバーロードできない演算子のリストです:

  • .:メンバーアクセス演算子
  • .*, ->*:メンバーポインタアクセス演算子
  • :::スコープ演算子
  • sizeof:サイズ演算子
  • ?::条件演算子
  • #:プリプロセッサ記号

演算子オーバーロードの例

以下にさまざまな演算子オーバーロードの例を示します。オーバーロードの概念をより深く理解するのに役立ちます。

番号演算子と例
1単項演算子のオーバーロード
2二項演算子のオーバーロード
3関係演算子のオーバーロード
4入出力演算子のオーバーロード
5++ および -- 演算子のオーバーロード
6代入演算子のオーバーロード
7関数呼び出し演算子 () のオーバーロード
8添え字演算子 [] のオーバーロード
9クラスメンバーアクセス演算子 -> のオーバーロード
その他の拡張