模板类使用友元函数重载操作符需要注意的问题

当我们在同一个cpp文件里使用friend函数重载操作符,但是声明和实现分开时,我们需要对friend函数的声明做特殊处理,否则会产生如下错误:

模板类friend函数在外面.obj : error LNK2019: 无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Complex<int> &)" (??6@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AEAV01@AEAV?$Complex@H@@@Z),该符号在函数 main 中被引用

具体解决办法由下面的一个实现进行说明:

#include <iostream>
using namespace std;

// 友元函数在类外面实现,并且都在同一个CPP文件中,需要在前面对类和对应操作符重载函数进行前置声明。
// 同时在类内部声明的对应函数需要在参数链表前加入 "<T>"。
template <typename T>
class Complex;           // 类前置声明
template <typename T>
Complex<T> operator++ (Complex<T> &c1, T);	// 函数前置声明

template <typename T>
class Complex{
public:
	Complex(T a = 0, T b = 0){
		this->a = a;
		this->b = b;
	}
	void print(){
		cout << a << " : " << b << endl;
	}
	//前置--
	Complex operator--(){
		Complex tmp = *this;
		this->a--;
		this->b--;
		return tmp;
	}
private:
	friend Complex<T> operator++ <T> (Complex<T> &c1, T);	// 后置需要增加一个占位
	friend ostream & operator<< <T> (ostream& out, Complex<T> &c2);

	T a;
	T b;
};

//后置++
template <typename T>
Complex<T> operator++(Complex<T> &c1, T){
	Complex<T> tmp = c1;
	c1.a++;
	c1.b++;
	return tmp;   // 由于是后置++,因此需要返回++前的对象
}

// "<<"和">>"由于函数重载,如果在同一个CPP里,但不在类内部实现,需要
// 在类内声明的时候在函数参数链表前加上"<T>"
template <typename T>
ostream & operator<< (ostream& out, Complex<T> &c2) {
	out << "a: " << c2.a << " b: " << c2.b << endl;
	return out;
}

void main(){
	Complex<int> c1(1, 2);

	// 友元函数重载运算符
	c1++;
	cout << c1 << endl;

	// 成员函数重载运算符
	--c1;
	cout << c1 << endl;

	cin.get();
	return;
}

从例子可以看出,在同一个文件内,函数声明和实现分开,友元函数重载运算符时分两种情况:

情况一:针对运算符"<<"和">>"

  • 在类中声明函数时需要在参数列表前加"<T>",如:friend ostream & operator<< <T> (ostream& out, Complex<T> &c2);
  • 在外面实现函数。

 

情况二:其他操作符

  • 在最前面进行类前置声明;
  • 在最前面进行函数的前置声明;
  • 类中声明函数时需要在参数列表前加"<T>"
  • 在外面实现函数;

注:

  • 以上的解决方法只是针对所有模板类代码都写在同一个CPP文件中,要是吧H和CPP文件分开,以上方法还是行不通。
  • 为了避免不必要的错误,建议在编写模板类时,把类方法的声明和实现写在一起,即直接在类的内部声明式同时实现。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值