スポンサードリンク
HOME > C++言語 > 演算子多重定義とは?

C++言語 - 演算子多重定義とは?

演算子多重定義とは、演算子に複数の機能を持たせる事です。

この機能によって非常に多彩な処理が可能になります。

なぜこの機能が必要なのかと言えば、

ユーザ定義型(クラス)が存在するからです。

例えば以下のようなプログラムがあったとします。

class myclass {
public:
int a;
};

void main(void) {
   myclass obj1, obj2, obj3;

   obj3.a = obj1.a + obj2.a;

}


このプログラムは、myclassのメンバ変数aを足す例です。

何も不思議な事はないごく普通のプログラムですが、

以下のような書き方ができれば便利だと思いませんか?

class myclass {
public:
int a;
};

void main(void) {
   myclass obj1, obj2, obj3;

   
obj3 = obj1 + obj2;
}


この足し算は通常、コンパイルエラーとなり、実行できませんが、

クラス同士の足し算を独自に実装する機能、すなわち、演算子多重定義を使えば、

このようなクラス同士の足し算が実現可能になります。

この場合、+(プラス)演算子を多重定義する形になります。

 この演算子の多重定義を実装する際にはポイントがあります。

「演算子には、第1の値と第2の値を演算して第3の値とする。」

と言うルールがあります。

この3つの値(データ型)によって演算子の多重定義の中身が変わります。


演算子の多重定義を実装する方法は3つあります。

1つ目は、クラスのメンバ関数で実装する方法。

2つ目は、クラスに対応するフレンド関数で実装する方法。

3つ目は、通常の関数で実装する方法です。

まずはクラスのメンバ関数で実装する例をご紹介します。

実装例

class myclass {
public:
int a;

myclass operator+(myclass obj2) {
   myclass temp;
   temp.a = this->a + obj2.a;
   return temp;
}


};

void main(void) {
   myclass obj1, obj2, obj3;

   obj3 = obj1 + obj2;
}


このプログラムは、myclassメンバ関数で演算子多重定義を実装した例です。

演算子多重定義のための関数は特殊な書き方が必要です。

operator+と表記されていますが、これは、演算子+(プラス記号)の事です。

演算子−(マイナス記号)の場合は、operator-となります。

そして、実際に使われているコードは、

obj3 = obj1 + obj2;

となっています。

これは、obj3 = obj1.operator+(obj2); と言うように関数形式として認識されます。

ここが非常に理解しづらい部分ですが、最重要ポイントです。

つまり、obj1operator+関数が呼ばれ、引数にはobj2が渡される。

と言う意味になります。

この意味を理解できれば、メンバ関数内の記述も自然と理解できる事でしょう。



クラスに対応するフレンド関数で実装する方法

上記のプログラムをフレンド関数で実装する例をご紹介します。

class myclass {
private:
int a;

friend myclass operator+(myclass obj1, myclass obj2);
};

myclass operator+(myclass obj1, myclass obj2) {
   myclass temp;
   temp.a = obj1.a + obj2.a;
   return temp;
}


void main(void) {
   myclass obj1, obj2, obj3;

   obj3 = obj1 + obj2;
}


フレンド関数として実装すると、引数が2つに増えています。

つまり、フレンド関数には演算子の第1の値(クラス)のthisポインタが渡されないので、

引数として、第1の値(クラス)、第2の値(クラス)を記述する事が必要になります。

こう言った記述方法は仕様ですので、多少分かりづらくても仕方がありません。

このプログラム内では、メンバ変数がprivate指定されていますが、

フレンド関数で実装されているので、メンバ変数aにアクセス可能となっています。




通常の関数で実装する方法

上記のプログラムを通常の関数で実装する例をご紹介します。

class myclass;
myclass operator+(myclass obj1, myclass obj2);

class myclass {
public:
int a;

};

myclass operator+(myclass obj1, myclass obj2) {
   myclass temp;
   temp.a = obj1.a + obj2.a;
   return temp;
}


void main(void) {
   myclass obj1, obj2, obj3;

   obj3 = obj1 + obj2;
}


まず、フレンド関数の場合と同じように引数は2つ記述が必要です。

通常の関数で実装すると、

関数内ではクラスのpublicメンバ変数にしかアクセスできない点が特徴です。

上の2行はプロトタイプ宣言です。



異なるデータ型同士の演算子多重定義

ここまでは同じクラス(データ型)同士の演算子多重定義を説明しましたが、

異なるデータ型同士の場合でも演算子の多重定義を実装する事が可能です。

例えば以下のような場合です。

void main(void) {
   myclass obj1, obj2, obj3;

   obj3 = obj1 + 5;
   obj3 = 5 + obj2;

}


まず、1つ目の obj1 + 5; の記述に対応する演算子多重定義関数を実装してみます。

class myclass {
public:
int a;

myclass(int data) { a = data; }

};

myclass operator+(myclass obj2) {
   myclass temp;
   temp.a = this->a + obj2.a;
   return temp;
}


void main(void) {
   myclass obj1, obj2, obj3;

   obj3 = obj1 + obj2;
}


obj1 + 5; の記述は、myclass型 + int型 となるため、

myclass operator+(int data); のような関数を追加しても良いですが、

1つの演算子多重定義関数で対応できるようになっています。

5と言う数値がoperator+関数の引数(myclass型)に渡せるようになっています。

これは、5がmyclass型に変換(つまり、myclass(5)と変換)されます。

myclass(5)と言うのは、コンストラクタを呼ぶ動作となります。

つまり、対応するメンバ変数に値を設定するコンストラクタが存在すれば、

新たにmyclass operator+(int data); と言う関数を作る必要はなくなります。


 次に2つ目の 5 + obj2; の記述ですが、これは少し厄介な感じです。

今までの考え方によると、5.operator+(・・・); のような感じになってしまいます。

5と言うのは、クラスではないので、こういう書き方はできません。

 こう言った場合は、クラスのメンバ関数による演算子多重定義関数は作れません。

フレンド関数か通常の関数で対応する必要があります。

フレンド関数と通常の関数では、対応するクラスに対するアクセス権だけが異なるので、

ここでは、フレンド関数のみご紹介します。

class myclass {
private:
int a;

friend myclass operator+(myclass obj1, myclass obj2);
friend myclass operator+(int data1, myclass obj2);

};

myclass operator+(myclass obj1, myclass obj2) {
   myclass temp;
   temp.a = obj1.a + obj2.a;
   return temp;
}


myclass operator+(int data1, myclass obj2) {
   myclass temp;
   temp.a = data1 + obj2.a;
   return temp;
}


void main(void) {
   myclass obj1, obj2, obj3;

   obj3 = obj1 + obj2;
   obj3 = obj1 + 5;
   obj3 =  5 + obj2;
}




スポンサードリンク







HOME

言語解説編
プログラミング用語・知識

C言語

C++言語

Java

C#

Visual Basic.NET

アプリケーション編
C言語による
コンソールプログラミング




Copyright (C) プログラミングランド All Rights Reserved