MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
C++の基礎 - フレンドのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
C++の基礎 - フレンド
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == <code>private</code>メンバは、そのメンバを持つクラスからのみアクセスできるが、例外的に、特定の相手にのみ<code>private</code>メンバへのアクセスを許可するフレンドがある。<br> フレンドは、特定の関数からのアクセスを許可するフレンド関数、および、特定のクラスからのアクセスを許可するフレンドクラスの2つが存在する。<br> <br> フレンドについては賛否両論あり、使用すべきではないという意見もある。<br> 実際に、<code>private</code>メンバへアクセスできる経路を作るため、使いどころには注意が必要となる。<br> <br> しかし、フレンドは相手を明確に限定しているため、特定の相手のためだけに<code>private</code>メンバを<code>public</code>メンバに変更するよりもよい方法だと言える。<br> フレンドを使用するかどうかを決定する前に、そのクラスのメンバにできないかどうかを考えるべきである。<br> <br><br> == フレンド関数 == 特定の関数に対してのみアクセスを許可するようなフレンドを、フレンド関数と呼ぶ。<br> 通常の関数、メンバ関数(staticメンバ関数も含む)、コンストラクタ、デストラクタ、オーバーロードされた演算子等の全ての関数が該当する。<br> また、関数テンプレートも指定できる。<br> <br> <code>friend</code>キーワードを使用して、フレンドにする関数を指定する。これを、<u>フレンド宣言</u>と呼ぶ。<br> フレンド宣言は、他の関数からもメンバにアクセスしていることを理解しやすくするため、クラス内の先頭に記述する方がよい。<br> <br> フレンド関数から、非staticメンバにアクセスする場合、そのクラスのオブジェクトが必要となる。(どのオブジェクトのメンバにアクセスするかが不明なため)<br> そのため、フレンド関数に渡す実引数により、オブジェクトを指定する必要がある。<br> <br> 以下の例において、フレンド関数がCSampleClass&型の引数を持つ理由は、どのオブジェクトのメンバにアクセスするかを明示する必要があるからであるが、<br> staticメンバ関数にアクセスする場合は、これは不要である。<br> <syntaxhighlight lang="c++"> class CSampleClass1 { friend void func(CSampleClass1& x); friend void CSampleClass2::func(CSampleClass1& x); // CSampleClass2の定義が必要となる // ...略 }; </syntaxhighlight> <br> また、フレンド関数にオーバーロードされた関数がある場合、フレンド関数にできる関数は、引数、戻り値、<code>const</code>等の全てが一致したものに限られる。<br> <syntaxhighlight lang="c++"> int main() { CSampleClass1 cls1, cls2; func(cls1); // cls2ではなくcls1にアクセスする } </syntaxhighlight> <br> メンバ関数をフレンド指定する場合は、そのメンバ関数が所属するクラスの定義が見える必要がある。<br> また、フレンド宣言の記述は、相手先のアクセス指定の影響を受けるため、上記の例でいうと、CSampleClass2::func関数は<code>public</code>にする必要がある。<br> <br> 以下の例では、CSampleClass1の前にCSampleClass2が必要で、CSampleClass2の前にCSampleClass1が必要という相反する要求になるため、クラスの前方宣言を行う必要がある。<br> <syntaxhighlight lang="c++"> class CSampleClass1; // クラスの前方宣言 class CSampleClass2 { public: // フレンド宣言を許可するため、publicメンバにする必要がある void func(CSampleClass1& x); }; class CSampleClass1 { friend void func(CSampleClass1& x); friend void Y::func(CSampleClass1& x); // ...略 }; </syntaxhighlight> <br> 以下の例では、関数テンプレートをフレンド指定している。<br> <syntaxhighlight lang="c++"> template <typename T> void func(T a); class CSampleClass { template <typename T> friend void func(T); }; </syntaxhighlight> <br> <code>template <typename T></code>の箇所が、<code>friend</code>指定子よりも前方にあることに注意する。<br> テンプレート仮引数の名前については、引数や戻り値で使用しない場合は省略できる。<br> <br> フレンド関数の存在意義として最も大きい理由として、演算子のオーバーロードを幅広く実現できることである。<br> 演算子の種類によっては、クラスの外部に記述しなければならないケースがある。<br> しかし、クラスの外部に記述する場合、<code>private</code>メンバにアクセスできないため実装が難しくなるが、フレンド関数を活用することにより簡潔に記述できる。<br> <br> 上記の用途以外でのフレンド関数の使用は原則として避けて、他の設計を検討した方がよい。<br> <br><br> __FORCETOC__ [[カテゴリ:C++]]
C++の基礎 - フレンド
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse