3

我试图了解将朋友声明注入命名空间:

#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
}

friendInject.cc:39: 错误:'func' 没有在这个范围内声明这本书说:“你可以通过在一个封闭的类中声明一个朋友声明到一个命名空间中”。“现在函数 you() 是命名空间 Me 的成员。”

这到底是什么意思??我试过 Y::func 但这可能只适用于静态成员函数?

4

2 回答 2

1

你必须写

y.func(&zx, 30); // work well

与 y。因为fund - 它是一个类实例方法

于 2012-07-16T13:33:03.660 回答
0

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。这样的友元声明“注入”什么都没有。

于 2012-07-16T17:00:53.160 回答