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

C/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;
}
		

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