天天看點

C++模闆類的使用以及運算符重載的實作

一、類模闆及運算符重載的實作

如同函數模闆一樣,使用類模闆使使用者可以為類定義一種模式,使得類中的某些資料成員、某些成員函數的參數、某些成員函數的傳回值能取任意類型。類模闆是對一批僅僅成員資料類型不同的類的抽象,程式員隻要為這一批類所組成的整個類家族建立一個類模闆,給出一套程式代碼,就可以用來生成多種具體的類,(這類可以看作是類模闆的執行個體),進而大大提高程式設計的效率。

定義類模闆的一般形式是:

template <類型名 參數名1,類型名 參數名2,…>
class 類名
{
  類聲明體
};
           

例如:

template <class T>
class complex{
	T a, b;
	public:
		complex(T, T);
		complex(){}
		void show();
		complex operator +(complex &);    // 聲明運算符 ‘+’ 的重載
		complex operator -(complex &);    // 聲明運算符 ‘-’ 的重載
};
           

在類模闆的外部定義類成員函數的一般形式如下所示:

template <類型名 參數名1,類型名 參數名2,…>
函數傳回值類型 類名<參數名 1 參數名 2,…>::成員函數名(形參表)
{
  函數體
}
           

例如:

template <class T>
complex<T> complex<T>::operator+(complex<T> &x1)
// 注意在模闆類外部進行定義時,傳回值以及形參的類型都需要為 complex<T>,而不能是 complex
{
	return complex(a+x1.a, b+x1.b);
}
           

類模闆是一個類家族的抽象,它隻是對類的描述,編譯程式不為類模闆(包括成員函數定義)建立程式代碼,但是通過對類模闆的執行個體化可以生成一個具體的類以及該具體類的對象。

與函數模闆不同的是:函數模闆的執行個體化是由編譯程式在處理函數調用時自動完成的,而類模闆的執行個體化必須由程式員在程式中顯式地指定,其執行個體化的一般形式是:

類名 <資料類型 1(或資料),資料類型 2(或資料)…> 對象名
           

例如:

complex<int> c1(1,2);         // 要根據自己定義的構造函數來确定是否添加參數
           

完整代碼如下所示:

#include <iostream>
using namespace std;

template <class T>
class complex{
	T a, b;
	public:
		complex(T, T);
		complex(){}
		void show();
		complex operator +(complex &);
		complex operator -(complex &);
};

template <class T>
complex<T>::complex(T x, T y):a(x), b(y){cout<<"Have create the complex!"<<endl;}

template <class T>
void complex<T>::show()
{
	cout<<a<<'+'<<b<<'i'<<endl;
}

template <class T>
complex<T> complex<T>::operator+(complex<T> &x1)
{
	return complex(a+x1.a, b+x1.b);
}

template <class T>
complex<T> complex<T>::operator-(complex<T> &x2)
{
	return complex(a-x2.a, b-x2.b);
}

void main()
{
	complex<int> c1(1,2);
	complex<int> c2(2,3);
	complex<int> c3 = c1+c2;
	complex<int> c4 = c2-c1;

	c1.show();
	c3.show();
	c4.show();
}
           

二、用友元函數實作運算符重載

關于友元函數有以下幾點說明:

1)C++中引入友元函數,是為在該類中提供一個對外(除了他自己意外)通路的視窗;
2)這個友元函數他不屬于該類的成員函數,他是定義在類外的普通函數,隻是在類中聲明該函數可以直接通路類中的private或者protected成員。
           

使用友元函數實作運算符重載如下所示:

#include "stdafx.h"


#include <iostream>
using namespace std;

template <class T>
class complex {
	T a, b;
public:
	complex(T, T);
	complex() {};
	void show();

	template <class T1>
	friend complex<T1> operator *(const complex<T1> &, const complex<T1> &);
};

template <class T>
complex<T>::complex(T x, T y) :a(x), b(y) { cout << "Have create the complex!" << endl; }

template <class T>
void complex<T>::show()
{
	cout << a << '+' << b << 'i' << endl;
}

template <class T1>
complex<T1> operator *(const complex<T1> &c1, const complex<T1> &c2)     // 由于友元函數不屬于類,是以在定義時不需要說明該函數屬于類
{
	T1 real = c1.a*c2.a - c1.b*c2.b;
	T1 ima = c1.a*c2.b + c2.a*c1.b;
	return complex<T1>(real, ima);
}

void main()
{
	complex<int> c1(1, 2);
	complex<int> c2(2, 3);
	complex<int> c3 = c1*c2;
	c3.show();
	system("pause");
}
           

繼續閱讀