スポンサードリンク
HOME > C++言語 > クラス機能 フレンド機能

C++言語 - クラス機能 フレンド機能

クラス内のprivateprotectedメンバ変数は、

基本的に、同じクラス内のメンバ関数からしかアクセスできません。

しかし、フレンド機能を使うと、通常の関数からもアクセスできるようになります。

フレンド機能には、フレンド関数フレンドクラスがあります。



フレンド関数

フレンド関数は、メンバ関数ではない通常の関数から、

あるクラスのprivateprotectedメンバ変数にアクセスしたい時に作成し、

関数内で、 あるクラスのprivateprotectedメンバ変数にアクセスできます。

フレンド関数利用例

ファイル名:hito.h
class hito {
private:
int age;

friend void func(hito obj);   // フレンド関数
friend void func(hito *obj);   // フレンド関数(ポインタ版)

};


ファイル名:hito.cpp
#include "hito.h"

void func(hito obj) {
   obj.age = 20;    // privateメンバ変数にアクセス
}

void func(hito *obj) {
   obj->age = 20;    // privateメンバ変数にアクセス
              // ポインタ版
}


ファイル名:main.cpp
#include "hito.h"

void main(void) {
   hito satou;
   func(satou);

   hito suzuki;
   func(&suzuki);

}


このプログラムでは、クラスhitoに対するフレンド関数を2つ作成し、

そのフレンド関数内からクラスhitoprivateメンバ変数へアクセスする例です。

まず始めにフレンド関数の定義ですが、

フレンド関数は、クラスのメンバ関数ではありませんが、クラス内に定義します。

この時、先頭にキーワードfriendを付けます。

フレンド関数に対するアクセス指定子(publicprivate等)は無視されます。

フレンド関数の実体は、通常の関数と同じように記述します。

この時、キーワード:friendを付ける必要はありません。

このような記述をする事で、クラスhitoとフレンド指定されたフレンド関数内で、

privateprotectedメンバ変数にアクセスする事ができるようになります。

フレンド関数はメンバ関数ではなく、通常の関数なので、

thisポインタが渡されません。(thisポインタの説明はコチラ

そのため、フレンド関数内でprivateprotectedメンバ変数へアクセスするには、

フレンド関数の引数にクラス型を設定してフレンド関数内からアクセスするか、

グローバル領域にクラスのインスタンスを作成しておき、

フレンド関数内からアクセスするか。になります。



フレンドクラス

フレンド関数は、クラスからフレンド指定してもらえれば、

フレンド関数内で、クラス内のprivateprotectedメンバ変数へアクセスできました。

しかし、フレンド関数を多数つくると言った場合には、

フレンドキーワードを付けた関数を1つ1つ書かなくてはなりません。

それは非常に効率が悪いので、

関数単位でフレンド指定する「フレンド関数」と言う機能よりも便利な

フレンドクラスと言う機能があります。

これは、クラス単位でフレンド指定できる機能です。

「クラス単位で」と言う意味は、クラス内の全てのメンバ関数がフレンド関数になる

と言う意味です。

フレンドクラス利用例

/********** クラスhito1 **********/

class hito1 {
private:
int age;

public:
hito1(int age) {this->age = age; }
friend hito2;  // フレンドクラス指定

};

/********** クラスhito2 **********/

class hito2 {
public:
void func1(hito1 obj);
void func2(hito1 obj);

};

void hito2::func1(hito1 obj) {
   obj.age = 20;   // privateメンバ変数にアクセス
}

void hito2::func1(hito1 obj) {
   obj.age = 20;   // privateメンバ変数にアクセス
}

/********** main関数 **********/

void main(void) {
   hito1 satou(10);
   hito2 suzuki;
   suzuki.func1(satou);  // フレンドクラスのメンバ関数呼び出し
   suzuki.func2(satou);  // フレンドクラスのメンバ関数呼び出し

}


この例では、クラスhito1の定義で、クラスhito2をフレンドクラスに指定しています。

こうすることにより、クラスhito2の全てのメンバ関数は、

クラスhito1に対するフレンド関数となります。

クラスhito2のメンバ関数定義では、キーワード:friendは必要ありません。

また、メンバ関数実体を記述する時は、通常のフレンド関数とは異なり、

クラスのメンバ関数となるので、スコープ解決演算子をつけて定義します。

さらに、クラスのメンバ関数なので、thisポインタが渡されます。

まとめると、フレンド指定するクラス側で、フレンドクラスを指定だけすれば、

指定された側のクラスは通常通りのクラス記述をすれば良い事となり、

キレイな仕様となっています。



スポンサードリンク







HOME

言語解説編
プログラミング用語・知識

C言語

C++言語

Java

C#

Visual Basic.NET

アプリケーション編
C言語による
コンソールプログラミング




Copyright (C) プログラミングランド All Rights Reserved