定义流IO的友元函数很常见,但随着项目变大,一般都将将类定义在某命名空间内,这时,我们在该类中定义的友元函数和命名空间是什么关系?如果该友元函数在类的cpp文件中实现,是放在命名空间内还是放在命名空间外?另外,对于该实现的函数,是否还需要给出函数声明?也就是说,friend能否承担声明友元函数的责任?
头文件:
#include <ostream>
namespace ns_test
{
/*
* type
*/
class CTestFriend
{
public:
CTestFriend(int i):
m_int(i)
{
// TODO Auto-generated constructor stub
}
virtual ~CTestFriend();
friend std::ostream & operator << (std::ostream & os, const CTestFriend & obj);
private:
int m_int;
};
} /* namespace ns_test */
CPP文件
#include "CTestFriend.h"
namespace ns_test
{
CTestFriend::~CTestFriend()
{
// TODO Auto-generated destructor stub
}
std::ostream & operator << (std::ostream & os, const CTestFriend & obj)
{
os << obj.m_int << "\n";
return os;
}
} /* namespace ns_test */
上述代码,在实际的测试中,友元函数实现必须在命名空间内,并且friend已经承担了函数声明的任务,在客户代码,只需要包含上述头文件即可;
如果将友元函数的实现放在命名空间外,编译时会提示,函数实现中无法访问CTestFriend类的私有成员,也就是说,编译器认为实现函数并不是该类的友元;
如果将friend声明改成friend std::ostream & ::operator << (std::ostream & os, const CTestFriend & obj);,编译器报该声明前,应该在全局声明该函数,所以,此时的friend并没有承担友元函数的声明任务。
以上,在gcc 版本 4.6.3上测试。有兴趣的朋友,也可以在其它编译器上试一试。