一、类模板及运算符重载的实现
如同函数模板一样,使用类模板使用户可以为类定义一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值能取任意类型。类模板是对一批仅仅成员数据类型不同的类的抽象,程序员只要为这一批类所组成的整个类家族创建一个类模板,给出一套程序代码,就可以用来生成多种具体的类,(这类可以看作是类模板的实例),从而大大提高编程的效率。
定义类模板的一般形式是:
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");
}