您的位置:首页 > 编程语言 > C语言/C++

C++ 模板类友元之输出流操作符重载

2016-07-12 18:02 351 查看
几个关键点:

  需要前置声明!--奇怪的是别人告诉我也可以不需要,但我这里不行!

  友元函数的函数名后面的[b]<>[/b],必须要有。

#include <stdio.h>
#include <iostream>
using namespace std;

//前置声明,你妹啊
template<class T> class A;
template<class T> ostream &operator<< (ostream &out, const A<T> &_a);
template<class T1, class T2> class B;
template<class T1, class T2> ostream &operator<< (ostream &out, const B<T1, T2> &_b);

template<class T> class A
{
public:
A(){}
A(T _a, T _b):a(_a),b(_b){}
~A(){}
private:
T a;
T b;

friend ostream &operator<< <> (ostream &out, const A<T> &a);
};

template<class T> ostream &operator<< (ostream &out, const A<T> &_a){
out<<_a.a<<"--"<<_a.b;
return out;
}

template<class T1, class T2> class B: public A<T1>
{
public:
B(){}
B(T1 _a, T1 _b, T2 _c):A<T1>(_a,_b),c(_c){} //A<T1>
~B(){}
private:
T2 c;

friend ostream &operator<< <>(ostream &out, const B<T1, T2> &_b);
};
template<class T1, class T2> ostream &operator<< (ostream &out, const B<T1, T2> &_b){
// out<<(A<T1>)_b;
// out<<"--"<<_b.c;

out<<(A<T1>)_b<<"--"<<_b.c;
return out;
}

int main(int argc, char const *argv[])
{
A<int> x(1, 3);
B<char, int> y('a', 'b', 5);

cout<< x <<endl;
cout<< y <<endl;

return 0;
}


View Code

以上认识太片面,请忽略。

[b]这里 [/b]有完美的解释!

大意如下:

模板类的友元其实有多个可能,关键在于这个友元是该模板类的一个/特定具现(实例)的友元,还是所有具现(实例)的友元。

注意1,这里不需要考虑与泛型无关的友元--例如输出一句话之类的,完全没有意义。

注意2,这里的多个可能是编译之前的可能,编译之后还是一个具现(实例)有一个友元(---猜测)。

总之,我认为,这两种仅仅是出发点不同,但最终目的地一致。

一、友元是模板类的一个/特定具现(实例)的友元,需要前置声明

#include <stdio.h>
#include <iostream>
using namespace std;

//前置声明,你妹啊
template<class T> class A;
template<class T> ostream &operator<< (ostream &out, const A<T> &_a);
template<class T1, class T2> class B;
template<class T1, class T2> ostream &operator<< (ostream &out, const B<T1, T2> &_b);

template<class T> class A
{
public:
A(){}
A(T _a, T _b):a(_a),b(_b){}
~A(){}
private:
T a;
T b;

friend ostream &operator<< <> (ostream &out, const A<T> &a);
};

template<class T> ostream &operator<< (ostream &out, const A<T> &_a){
out<<_a.a<<"--"<<_a.b;
return out;
}

int main(int argc, char const *argv[])
{
A<int> x(1, 3);
cout<< x <<endl;

return 0;
}


二、友元是所有具现(实例)的友元,不需要前置声明:

#include <iostream>

using namespace std;

//友元operator<< 是模板类A的所有实例的友元(实际上还是多个operator<<)--不需要前置声明。
template <typename T>
struct A {
T a;
A(T _a) :a(_a) {}

template <typename T1> friend ostream &operator<< (ostream &out, const A<T1> &_a);//这里的T1?? 由于<<输出的是A的实例的对象,所以实际上这里的T1编译之后还是T--因为编译器找不到其他可能。
};

template <typename T>
ostream & operator<< (ostream & out, const A<T> &_a) {
out << _a.a;
return out;
}

int main() {
A<int> x(15);
cout << x << endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: