c++类的friend函数问题

来源:百度知道 编辑:UC知道 时间:2024/06/01 00:27:35
一共有3个文档,以下是代码:
//***************************************
// test.h -- prototype

template<class T>
class a{
public:
class b{
public:
friend void bb(b bn);
};
};

//****************************************
// test1.h -- definition

#include "test.h"

template<class T>
void bb(typename a<T>::b bn){}

//***************************************
// test.cpp -- a problem occur

#include "test1.h"

int main( ){
a<int>::b test;
bb(test);
}

//**************************************
我在vc2005ex下编译时出现以下错误提示:
test.obj : error LNK2019: unresolved external symbol "void __cdecl bb(class a<int>::b)" (?bb@@YAXVb@?$a@H@@@Z) referenced in function _main

看样子问题是出在friend函数bb上了。
我的问题:
1、friend函数不管在类或者类的嵌套类中声明以后其作用域都为全局(globe scope)?
2、有没有避免让friend函数成为全局函数的方

首先,模板的定义文件和声明头文件不要分开,目前来说,gcc和msvc80还都不支持分开。
第二,这个问题属于模板friend函数问题,是不能那么简单的将声明与定义分开的,就算放在同一个文件,也会报错的。有两种办法,第一种,直接将函数的定义放在声明的地方,这种,目前大部分的编译器都支持。第二种,相对来说,就比较麻烦了,而且,有的编译器还不支持,举个简单的例子说明一下:

template<class T>
class A;

template<class T>
void f(A<T>);

template<class T>
class A {
public:
friend void f<>(A<T> a);
};

template<class T>
void f(A<T> a)
{
// some implementation
}
这样才是可以的,可以看一下《Thinking in c++,volume 2》
建议用第一种,简单明了

第三,你的前两个问题都是肯定的,关于第三个,之所以链接失败,是因为模板的问题,只要遵循我说的前面两条就没有问题了。另外,ADL(Argument-dependent lookup),可以看一下《inside c++ object model》
good luck

friend void bb(b<T> bn);

不知道对不对,感觉问题就是出在模版的部分
vc对模版支持不是很完全的

把 test.h 和 test1.h 合并就解决了....跟模板没关系

建议你不要使用友元方式访问私有和保护成员,重载类方法更通用,友元的方式会造成设计混乱,凡是写过C++程序的人都应该知道....