第10回は
演算子のオーバーロードについてです。

なんと、演算子も関数だった!?
(な、なんだってー)

基本的にはクラス内の演算子をオーバーロードします
2項演算子のオーバーロードは次のようになります

演算結果 operator 演算子(演算子の右辺)

書き方が難しいですが・・・
ちなみに左辺はクラス内部の変数となります
つまり

A + B

とやったとき
Aの+演算子関数が呼ばれます

ためしに自作Int型を作って
演算子をオーバーロードして
計算してみましょう

	#include <iostream>
	using namespace std;
	
	class Int{
	
	public:
		int data;
	
		Int(){}
		// コンストラクタ
		Int(int Data):data(Data){}	
		~Int(){}
	
		// 代入演算子のオーバーロード
		Int& operator=(const Int& Obj){
			cout << "call equal operator" << endl;
                       // this->はクラス内変数にアクセスするキーワード
			this->data = Obj.data;
			return *this;
		}
	
		// 加算演算子のオーバーロード
		Int operator+(const Int& Obj){
			cout << "call add operator" << endl;
                       // this->はクラス内変数にアクセスするキーワード
			return Int(this->data + Obj.data);
		}
	
	};
	
	int main(){
	
		Int a(5),b(10);
		Int c;
		c = a + b;
		cout << "c = " << c.data << endl;
	
		return 0;
	}

あまり恩恵を感じられないと思うので
より実践的な例を挙げときます
2次元ベクトルクラスの一部です
演算子のオーバーロードを使用することで
x,y2つのパラメータを同時に計算することができます

	#include <iostream>
	using namespace std;
	
	class Vector2
	{
	private:
		float x,y;
	public:
	
		// コンストラクタ
		Vector2():x(0),y(0)
		{}
		// コンストラクタ
		Vector2(float X,float Y):x(X),y(Y)
		{}
		// デストラクタ
		~Vector2()
		{}
	
		// 代入演算子のオーバーロード
		Vector2& operator =(const Vector2& obj){
			// this->はクラス内変数にアクセスするキーワード
			// クラス内のx,yに値代入
			this->x = obj.x;
			this->y = obj.y; 
			return *this;
		} 
	
		// 加算代入演算子のオーバーロード
		Vector2& operator +=(const Vector2& obj){
			// this->はクラス内変数にアクセスするキーワード
			// クラス内のx,yに値代入
			this->x += obj.x;
			this->y += obj.y;
			return *this;
		} 
	
		// 加算代入演算子のオーバーロード
		Vector2 operator +(const Vector2& obj){
			Vector2 vec;
			// this->はクラス内変数にアクセスするキーワード
			// クラス内のx,yに値代入
			vec.x = this->x + obj.x;
			vec.y = this->y + obj.y;
			return vec;
		} 
	
		// 配列のオーバーロード
		float operator [](unsigned int i){
			// このベクトルの先頭アドレス
			float *p = &x;
			return p[i];
		}
	
		// 単行演算子のオーバーロード
		Vector2& operator++(){
			this->x++;
			this->y++;
			return *this;
		}
	
		// 値をみる
		void Show(){
			cout << "x = " << x << endl;
			cout << "y = " << y << endl;
		}
	};
	
	int main(){
		Vector2 vec1;
		Vector2 vec2(1.0f,2.0f);
		Vector2 vec3;
		cout << "vec1" << endl;
		vec1.Show();
		cout << "vec2" << endl;
		vec2.Show();
		cout << "-----------------" <<endl;
	
		vec1 = vec2;
		cout << "vec1" << endl;
		vec1.Show();
		++vec1;
		cout << "vec1" << endl;
		vec1.Show();
		vec1 += vec2;
		cout << "vec1" << endl;
		vec1.Show();
		vec3= vec1 + vec2;
		cout << "vec3" << endl;
		vec3.Show();
		cout << "vec3" << endl;
		cout << "x = " << vec3[0] << endl;
		cout << "y = " << vec3[1] << endl;
	
		return 0;
	}

ほかにも-演算子やら*演算子やらオーバーロードしないと
実用的ではありませんがそれは各自実装してください。

new、delete演算子などもオーバーロードすることができます

       #include <new>	// new オーバーロード用
	#include <iostream>
	using namespace std;
	
	// new演算子のオーバーロード
	// size 作成するオブジェクトのサイズ
	void* operator new(size_t size) {
		printf("This is operator new! size = %d\n", size);
		return malloc(size);
	}
	
	// new[]演算子のオーバーロード
	void* operator new[](size_t iSize) {
		printf("This is oparator new[] size = %d\n", iSize);
		return malloc(iSize);
	}

	// delete 演算子のオーバーロード
	void operator delete(void* pv) {
		printf("This is operator delete!\n");
		free(pv);
	}
	
	// delete []演算子のオーバーロード
	void operator delete[](void* pv) {
		printf("This is operator delete[]!\n");
		free(pv);
	}
	
	class Vector2
	{
	private:
		float x,y;
	public:
	
		// コンストラクタ
		Vector2()
		{
			cout << "create" << endl; 
		}
		// デストラクタ
		~Vector2()
		{
			cout << "destroy" << endl; 
		}
	};
	
	int main(){
		// new deleteのオーバーロードはコンパイラによって動作違うみたいなので
		// 使うときは慎重に、極力使わないように!
	
		// operator new 
		Vector2* newdel = new Vector2;
		// operator delete 
		delete newdel;
		// operator new[]
		Vector2* newdelarray = new Vector2[2];
		// operator delete[]
		delete[] newdelarray;
	
		return 0;
	}

new、delete演算子はアロケータ(メモリ割り当て、管理をするクラス)を
作成するときに必要ですが、それ以外では使わないので
極力使わないほうが無難でしょう
ただし、オーバーロードできるものであるという認識は重要です

演算子のオーバーロードは
使い方を間違えると非常にわかりにくくなるので
ベクトルクラスなどの計算以外での使用は極力避けたいものです
ただし、うまく使えば非常に強力なものなので
覚えておいて損はないはずです
ネタとしてはほかにも推論エンジンなどの
面白い使い方などができるような気がします

選択肢 投票
(^ω^)わかったお 1  
普通 0  
。(`ω´#)。わかりにくぃぜぇえええええ 0  

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-12-14 (木) 17:52:24