一、问题代码及报错提示:
#include <iostream>
using namespace std;
template<class T>
class Person{
public:
template<class T>
friend ostream& operator<<(ostream& out,Person<T> &p);
public:
//重载输出运算符
Person(T age,T id);
void Show();
private:
T mAge;
T mID;
};
template<class T>
Person<T>::Person(T age,T id)
{
this->mAge = age;
this->mID = id;
}
template<class T>
void Person<T>::Show()
{
cout<<"mAge:"<<this->mAge<<" "<<"mID"<<this->mID<<endl;
}
template<class T>
ostream& operator<<(ostream& out,Person<T> &p)
{
out<<"mAge:"<<p.mAge<<" "<<"mID"<<p.mID<<endl;
return out;
}
void test01()
{
Person<int> p(20,10);
// p.Show();
cout<<p;
}
int main(int argc, char *argv[])
{
test01();
cout << "Hello World!" << endl;
return 0;
}
二、原因剖析
因为代码中用到类模板template<class T>而在类内声明的友元函数也用到了<T>,此时友元函数是依赖于类的实现的,所以编译器会报错
对此我们有几种解决方案:
1.改变友元与类模板的对应关系为多对多(若类模板使用的是template<class T>,友元函数就使用template<class U>来实现),代码如下:
#include <iostream>
using namespace std;
template<class T>
class Person{
public:
template<class U>
friend ostream& operator<<(ostream& out,Person<U> &p);
public:
//重载输出运算符
Person(T age,T id);
void Show();
private:
T mAge;
T mID;
};
template<class T>
Person<T>::Person(T age,T id)
{
this->mAge = age;
this->mID = id;
}
template<class T>
void Person<T>::Show()
{
cout<<"mAge:"<<this->mAge<<" "<<"mID"<<this->mID<<endl;
}
template<class U>
ostream& operator<<(ostream& out,Person<U> &p)
{
out<<"mAge:"<<p.mAge<<" "<<"mID"<<p.mID<<endl;
return out;
}
void test01()
{
Person<int> p(20,10);
// p.Show();
cout<<p;
}
int main(int argc, char *argv[])
{
test01();
cout << "Hello World!" << endl;
return 0;
}
2.改变友元与类模板的关系为一对一(朋友关系被限定在相同类型的实例化)代码如下:
#include <iostream>
using namespace std;
//前置声明
template<class T>
class Person;
template<class T>
ostream& operator<<(ostream& out,Person<T> &p);
template<class T>
class Person{
public:
friend ostream& operator<<<T>(ostream& out,Person<T> &p);
public:
Person(T age,T id);
void Show();
private:
T mAge;
T mID;
};
template<class T>
Person<T>::Person(T age,T id)
{
this->mAge = age;
this->mID = id;
}
template<class T>
void Person<T>::Show()
{
cout<<"mAge:"<<this->mAge<<" "<<"mID"<<this->mID<<endl;
}
template<class T>
ostream& operator<<(ostream& out,Person<T> &p)
{
out<<"mAge:"<<p.mAge<<" "<<"mID"<<p.mID<<endl;
return out;
}
void test01()
{
Person<int> p(20,10);
// p.Show();
cout<<p;
}
int main(int argc, char *argv[])
{
test01();
cout << "Hello World!" << endl;
return 0;
}
3.使用普通友元函数PrintPerson来实现,代码如下:
#include <iostream>
using namespace std;
template<class T>
class Person{
public:
//普通友元函数的声明
template<class U>
friend void PrintPerson(Person<U>& p);
public:
Person(T age,T id);
void Show();
private:
T mAge;
T mID;
};
template<class T>
Person<T>::Person(T age,T id)
{
this->mAge = age;
this->mID = id;
}
template<class T>
void Person<T>::Show()
{
cout<<"mAge:"<<this->mAge<<" "<<"mID"<<this->mID<<endl;
}
//普通友元函数的实现
template<class U>
void PrintPerson(Person<U>& p)
{
cout<<"mAge:"<<p.mAge<<" "<<"mID"<<p.mID<<endl;
}
void test01()
{
Person<int> p(20,10);
// p.Show();
//cout<<p;
PrintPerson(p);
}
int main(int argc, char *argv[])
{
test01();
cout << "Hello World!" << endl;
return 0;
}