フレンド

C++クラス X のフレンドとは、X のメンバーではないが、X のメンバーと 同じ X へのアクセスを認可されている関数またはクラスです。 クラス・メンバー・リスト内で、friend 指定子を使用して宣言された関数は、 そのクラスのフレンド関数 と呼ばれます。 別のクラスのメンバー・リスト内で friend 指定子を用いて宣言されたクラスは、そのクラスのフレンド・クラス と呼ばれます。

クラス Y を定義してからでなければ、Y の任意のメンバーを、別のクラスのフレンドとして宣言することはできません。

以下の例では、フレンド関数 print は、クラス Y のメンバーであり、 クラス X の private データ・メンバー a および b にアクセスします。

#include <iostream>
using namespace std;
 
class X;
 
class Y {
public:
  void print(X& x);
};
 
class X {
  int a, b;
  friend void Y::print(X& x);
public:
  X() : a(1), b(2) { }
};
 
void Y::print(X& x) {
    cout << "a is " << x.a << endl;
    cout << "b is " << x.b << endl;
}
 
int main() {
  X xobj;
  Y yobj;
  yobj.print(xobj);
}

次に、上記の例の出力を示します。

a is 1
b is 2

クラス全体をフレンドとして宣言することができます。 クラス F が、クラス A のフレンドであるとします。 メンバー関数、およびクラス F の静的データ・メンバー定義はいずれも、クラス A に アクセスすることができます。

次の例では、フレンド・クラス F には、クラス X の private データ・メンバー a および b にアクセスする、メンバー関数 print があります。 これは、前述の例のフレンド関数 print と同じタスクを実行します。 また、クラス F に宣言されたその他のメンバーも、クラス X のメンバーすべてにアクセスできます。

#include <iostream>
using namespace std;
 
class X {
  int a, b;
  friend class F;
public:
  X() : a(1), b(2) { }
};
 
class F {
public:
  void print(X& x) {
    cout << "a is " << x.a << endl;
    cout << "b is " << x.b << endl;
  }
};
 
int main() {
  X xobj;
  F fobj;
  fobj.print(xobj);
}

次に、上記の例の出力を示します。

a is 1
b is 2

クラスをフレンドとして宣言する場合は、詳述型指定子を使用する必要があります。 次の例は、このことを示しています。

class F;
class G;
class X {
  friend class F;
  friend G;
};
 

コンパイラーは、G のフレンド宣言が、詳述クラス名でなければならないことを警告します。

フレンド宣言では、クラスを定義できません。 例えば、コンパイラーは、次の表記を許可しません。

class F;
class X {
  friend class F { };
};

しかし、フレンド宣言で関数を定義することができます。 クラスは非ローカル・クラス関数になっている必要があり、関数名は非修飾で、関数はネーム・スペース・スコープを 持っている必要があります。 次の例は、このことを示しています。

class A {
  void g();
};
 
void z() {
  class B {
//    friend void f() { };
  };
}
 
class C {
//  friend void A::g() { }
  friend void h() { }
};

コンパイラーは、f() または g() の関数定義を許可しません。 コンパイラーは、h() の定義は認めます。

ストレージ・クラス指定子を使用して、フレンドを宣言することはできません。

関連参照

IBM Copyright 2003