关于C++类模板内部 / 外部声明友元模板函数的那些事儿

关于C++类模板内部 / 外部声明友元模板函数的那些事儿

1.内部声明定义友元类模板函数

例:


using namespace std;

template <typename T>
class Complex
{
	friend ostream& operator<<(ostream& out, Complex& c)
	{
		out << c.a << "," << c.b ;
		return out;
	}
public:
	Complex(T a, T b) :a(a),b(b){}
	Complex operator+(Complex& c)
	{
		Complex temp(this->a + c.a, this->b + c.b);
		return temp;
	}
private:
	T a;
	T b;
};

int main()
{
	Complex<int> a(1,2);
	Complex<int> b(3, 4);

	Complex<int> c = a + b;
	cout << c << endl;

	return 0;
}

运行结果: alt

2.内部声明,外部定义友元类模板函数

例:

using namespace std;

template <typename T>
class Complex {

    friend ostream& operator<<(ostream& out, Complex<T>& c);

public:
    Complex(T a, T b);

    Complex<T> operator+(Complex<T>& c);

private:
    T a;
    T b;
};

template <typename T>
ostream& operator<<(ostream& out, Complex<T>& c)
{
    out <<"(" << c.a << " , " << c.b << ")";
    return out;
}

template <typename T>
Complex<T>::Complex(T a, T b)
{
    this->a = a;
    this->b = b;
}

template <typename T>
Complex<T> Complex<T>::operator+(Complex<T>& c)
{
    Complex temp(this->a + c.a, this->b + c.b);
    return temp;
}


int main()
{
    Complex<int> c1(1, 2);
    Complex<int> c2(3, 4);

    Complex<int> c = c1 + c2;
    cout << c << endl;
    return 0;
}

运行结果:alt

别看啦大兄弟,这里出错也就是意料之中的事情,原因可以看下面:

这就是典型的 二次编译 的错误信息,找不到友元函数的函数实现。所以,如果友元模板函数的定义写在函数的外部,需要进行类和函数的前置声明,来让编译器找到函数的实现。

解决方法很简单,前置声明将能完美解决:

alt

运行结果: alt

3.声明在.h文件,定义在.cpp文件

例: alt

using namespace std;
#include "demo.hpp"


int main()
{
    Complex<int> c1(1, 2);
    Complex<int> c2(3, 4);

    Complex<int> c = c1 + c2;

    cout << c << endl;

    return 0;
}
using namespace std;

template <typename T>
class Complex;

template <typename T>
ostream& operator<<(ostream& out, Complex<T>& c);

template <typename T>
class Complex {

    friend ostream& operator<< <T> (ostream& out, Complex<T>& c);

public:
    Complex(T a, T b);

    Complex<T> operator+(Complex<T>& c);

    Complex<T> myAdd(Complex<T>& c1, Complex<T>& c2);

private:
    T a;
    T b;
};

template <typename T>
ostream& operator<<(ostream& out, Complex<T>& c)
{
    out <<"("<< c.a << " , " << c.b << ")";
    return out;
}

template <typename T>
Complex<T>::Complex(T a, T b)
{
    this->a = a;
    this->b = b;
}

template <typename T>
Complex<T> Complex<T>::operator+(Complex<T>& c)
{
    Complex temp(this->a + c.a, this->b + c.b);
    return temp;
}

template <typename T>
Complex<T> Complex<T>::myAdd(Complex<T>& c1, Complex<T>& c2)
{
    Complex temp(c1.a + c2.a, c1.b + c2.b);
    return temp;
}

这就是类模板的应用过程。

全部评论

相关推荐

1 1 评论
分享
牛客网
牛客企业服务