最近刚学了C++的模板类设计,刚开始上手的时候,总是会有一大堆的bug 摆在那里,确实模板作为多态实现的一种方式,很多时候需要我们去设想和顾虑很多方面的事情,一不留神就会造成出错。而且模板类在编译的时候并不会有什么问题,模板类只有在具体的模板类具体化之后才会显现出来。至少对于我来说还是挺头痛的。
那今天我就记录一下自己在模板类设计的时候容易犯的错误。
模板类的运算符重载
再用友元函数重载>>和<<这些运算符的时候千万不要把函数定义写在类定义外面!!
再用友元函数重载>>和<<这些运算符的时候千万不要把函数定义写在类定义外面!!
再用友元函数重载>>和<<这些运算符的时候千万不要把函数定义写在类定义外面!!
重要的事情说三遍。
代码如下:
#include "stdafx.h"
#include <iostream>
using namespace std;
template<class T>
class Test
{
public:
Test(const T& t):data(t){}
//---------------------------------------------
friend ostream& operator<<(ostream& out,Test<T>& t) //输出流重载声明及实现
{
return out<<"data is "<<t.data;
} //--------------------------------------------
friend istream& operator>>(istream& in,Test<T>& t) //输入流重载声明及实现
{
return in>>t.data;
}//---------------------------------------------
private:
T data;
};//-----------------------------------------------------------------
int main()
{
Test<int> b(3);
cout<<b<<'\n';
cin>>b;
cout<<b<<'\n';
return 0;
}
那么输入输出流重载为什么不能在类内声明,类外实现呢??因为模板比较特殊,若果在模板类外实现重载的话:
template<class T>
ostream& operator<<(ostream& out,Test<T>& t)
{
return out<<"data is "<<t.data;
} //--------------------------------------------
上面正好是函数模板的定义,而我们知道操作符重载函数不是类的成员函数,因此此处相当于定义了一个新的函数模板(不同于类中的friend ostream& operator<<(ostream& out,Test<T>& t) )
。但若去掉template<class T>
,函数中的参数Test<T>就不知是什么类型,所以不能在模板类内声明,类外实现操作符重载。
网友评论