静岡理工科大学 菅沼ホーム 目次

C++自学・自習(第11章)

第11章 演算子のオーバーロード

  1. (プログラム例11.1) ベクトルの加算(メンバー関数)
  2. (プログラム例11.2) ベクトルの加算(フレンド関数)

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

  クラスのオブジェクトどうしの演算はできないでしょうか.例えば,2 次元ベクトルに対応する次のようなクラスを宣言したとします.
	class Vector {
		double x[2];
	}
		
このとき,
	Vector a,b,c;
	c = a + b;
		
のようなことが可能であれば,ベクトルどうしの演算を普通のスカラーと同じように書くことができ,非常に便利です.

  C++ には,上のことを可能にするため,演算子のオーバーロード(多重定義,operator overloading )という機能があります.演算子のオーバーロードは,一部の演算子を除くすべての演算子に対して可能です.例えば,上の場合のように,+ 演算子に対してオーバーロードを行いたければ,希望する + 演算を実行する関数
	operator+
		
を定義してやればよいわけです.コンパイラは,+ 演算子に出会うと,それが結びつけている各項の型を判断し,基本データ型であれば普通の演算を,また,オーバーロードの際宣言されたクラスのオブジェクトであれば,オーバーロードの定義に従った演算を行います.

  演算子のオーバーロードを行うときは,以下のような規則に従う必要があります.

  1. 演算子は,メンバー関数,または,フレンド関数で定義します.ただし,次の演算子に対するオーバーロードは,メンバー関数で記述してやる必要があります.
    	=  : 代入
    	() : 関数呼び出し
    	[] : 添え字
    	-> : 間接参照
    			
  2. C++ に最初から備わっている演算子だけに定義でき,** (ベキ乗)のような新しい演算子を作成することはできません.
  3. 文法や演算子の優先順位の変更はできません.
  4. 基本データ型(クラスでない型)に対する演算子のオーバーロードは不可能です.

  以下の 2 つのプログラム例は,ベクトルの加算演算をメンバー関数,及び,フレンド関数を使用して書いた場合の例です.2 つの方法の違いを理解して下さい.

(プログラム例11.1) ベクトルの加算(メンバー関数) ( A 〜 B の部分を可能な限り一つの変数,定数,演算子等で,埋めてください.その際,文字を削除してから,正しい答えを半角文字で,かつ,余分なスペースを入れないで入力してください.)

  このプログラムでは,メンバー関数を使用して,2 次元のベクトルの和(要素どうしの和)を行う + 演算を定義しています.この関数の引数が 1 つしかない理由は以下の通りです.例えば,
	c = a + b;
		
を行う場合,operator+ はメンバー関数であるので,上の演算は,
	c = a.(operator+)(b);
		
と解釈され,下の例のように,関数内で最初のオブジェクト a のメンバーを直接参照できるからです.

(プログラム例11.2) ベクトルの加算(フレンド関数)

  上の例と同じ内容を,フレンド関数を使用して実現しています.引数の違いに注意して下さい.
	/**************************************/
	/*     ベクトルの加算(フレンド関数) */
	/*          coded by Y.Suganuma       */
	/**************************************/
	#include <stdio.h>
	
	/**************************/
	/*     クラスvectorの定義 */
	/**************************/
	class Vector {
			double x[2];
		public:
			void input();
			void output();
		friend Vector operator+ (Vector &a, Vector &b);
	};
	
	/**************************/
	/*     +のオーバーロード */
	/**************************/
	Vector operator+ (Vector &a, Vector &b)
	{
		Vector c;
		c.x[0] = a.x[0] + b.x[0];
		c.x[1] = a.x[1] + b.x[1];
		return c;
	}
	
	/**************************/
	/*     ベクトル要素の入力 */
	/**************************/
	void Vector::input()
	{
		printf("   2つの値を入力してください ");
		scanf("%lf %lf", &(x[0]), &(x[1]));
	}
	/**************************/
	/*     ベクトル要素の出力 */
	/**************************/
	void Vector::output()
	{
		printf("%f %f\n", x[0], x[1]);
	}
	
	/****************/
	/*     main関数 */
	/****************/
	int main()
	{
		Vector a, b, c;
	
		printf("a\n");
		a.input();
		printf("b\n");
		b.input();
	
		c = a + b;
	
		c.output();
	
		return 0;
	}
		

静岡理工科大学 菅沼ホーム 目次 前章 次節