C++ 将友元声明注入命名空间,Eckel,Vol1,pg:440?

C++ 将友元声明注入命名空间,Eckel,Vol1,pg:440?,c++,C++,我试图理解将友元声明注入命名空间: #include <iostream> using namespace std; namespace Z { //forward declaration class X; } class Y { public: void func(Z::X*, int); }; namespace Z { class X { int i; public: X() : i(999) {} friend vo

我试图理解将友元声明注入命名空间:

#include <iostream>
using namespace std;

namespace Z { //forward declaration
  class X;
}

class Y {
   public:
   void func(Z::X*, int);
 };

namespace Z {
  class X {
    int i;
    public:
    X() : i(999) {}
    friend void Y::func(Z::X*, int);
    void print(void) { cout << i << endl; }
  };
}


void Y::func(Z::X* ptr, int i)
{
  ptr->i = 40;
}

int main(void)
{
  Z::X zx;
  zx.print();

  Y y;
  y.func(&zx, 40);
  zx.print();

  using namespace Z;
//  func(&zx, 30); DOES NOT WORK
}
#包括
使用名称空间std;
名称空间Z{//前向声明
X类;
}
Y类{
公众:
void func(Z::X*,int);
};
名称空间Z{
X类{
int i;
公众:
X():i(999){}
friend void Y::func(Z::X*,int);
无效打印(void){cout你必须写

y.func(&zx, 30); // work well
对于y.因为基金-它是一个类实例方法

C++11标准7.3.1.2(3)说:

“如果非局部类中的友元声明首先声明一个类或函数[脚注:这意味着该类或函数的名称是非限定的],则友元类或函数是最内层封闭命名空间的成员。”

因此,任何非限定的友元函数声明都会在最内层的封闭名称空间中引入一个自由函数;(可能)本书将其称为“注入名称空间”

请注意,甚至可以在友元声明中定义(实现)函数:

namespace Z
{
  class C
  {
    friend void f(void){/*do something*/}
  };
}
这个友元声明不仅“注入”,而且还实现了命名空间Z中的自由函数f(f本身不是类C的成员!),因此Z::f不需要其他声明或定义

至于你的例子,

friend void Y::func(Z::X*, int);

是限定的(前缀为名称空间/类名),因此它不声明函数,它只引用以前在类Y中声明的成员函数Y::func。这样的友元声明不会“注入”任何内容。

您能否详细说明一下……他所说的“注入”友元声明到名称空间中的确切含义是什么?Y.func()当然可以,但作者的意思是更多的..与名称空间有关的东西Zcouldn你不可以从你的书中添加带有“function you()”的代码吗?或者什么是page and book?我试着找到它自己www.lib.ru.ac.th/download/e-books/TIC2Vone.pdf(pg:440)“现在函数you()是名称空间Me的成员。”这是错误的。如果我像书中的例子那样声明函数,函数“you”将不会成为名称空间“Me”的成员@Ilya:它将成为名称空间“Me”的成员。实际上,在这个朋友声明之后,您可以在程序中尽可能调用函数Me::you()(该函数不需要其他声明).我敢打赌,在书中的例子中,这位朋友不是另一个班级的成员。这会有很大的不同!