友元函数定义在类内部的问题

C++ primer上说友元函数定义在类内部的话,作用域是包含类定义的外围作用域。但是写代码测试后,有疑惑。以下代码在gcc和vc上都无法通过编译。提示找不到全局的hello

hello()的确被定义为全局函数,但是外面调用hello()的时候找不到函数定义,实际上根本就不知道这个函数被定义过,因为在作用域内没有声明。在外面加一行设声明即可。

#include <iostream>

class A
{
public:
    friend void hello() { std::cout << "Hello" << std::endl; }
};

void hello();

class B
{
public:
    void test() { ::hello(); }
};

int main() 
{  
    B b;
    b.test();
    return 0;
}

追问

这和C++ primer 4th P398 的描述矛盾。此种写法该友元函数的连接属性是什么呢?external还是static的?

追答

参见C++标准7.3.1.2节第三段:
The name of the friend is not found by unqualified lookup (3.4.1) or by qualified lookup (3.4.3) until a matching declaration is provided in that namespace scope (either before or after the class definition granting friendship). If a friend function is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments (3.4.2).
C++标准3.4.2节(Argument-dependent name lookup)第四段:
Any namespace-scope friend functions or friend function templates declared in associated classes are visible within their respective namespaces even if they are not visible during an ordinary lookup (11.3).
也就是说,除非友元函数带了class A的参数,可以通过Argument-dependent name lookup(ADL)被找到,否则必须在作用域里有声明才能在作用域中可见。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-01-29
VC6.0能顺利编译通过,已测试追问

VC6不是很符合ISO C++标准, 我在gcc 4.8.2和VC 2010下都无法编译成功

第2个回答  2014-01-29
// gz.cpp : Defines the entry point for the console application.
// email:573827574 2014/1/29
//
#include<stdio.h>
#include<stdafx.h>
#include<stdlib.h>
#include <iostream>
#include<stdio.h>

class A{
public:
A(void);
friend void hello();
virtual ~A(void);
};

class B {
public:
void test(){
::hello();
};
};

//放到外面来实现
void hello()
{
std::cout<<"Hello"<<std::endl;
}

void main()
{

B demo;
demo.test();
//fflush(stdin);
system("pause");

}追问

我的问题就是友元函数在类定义内部实现的问题。非内联的实现我知道可以编译。

追答

我VS2005也编译通过的啊。
好像书上说只允许构造函数、析构函数内联。

本回答被网友采纳
相似回答