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で。ファンドのため-そのクラスインスタンスメソッド

于 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 に答える