C++における継承とfriend(フレンド)関数の関係を解説
C++では、friend(フレンド)関係は継承されないという重要なルールがあります。つまり、親クラスにfriend関数が定義されていても、その子クラスは自動的に同じfriend関数を受け継ぐことはありません。
このため、親クラスのプライベートメンバーやプロテクテッドメンバーにはアクセスできても、子クラスのメンバーにはアクセスできないという状況が発生します。以下の例では、display()関数はMyBaseClassのfriendとして宣言されていますが、MyDerivedClassのfriendではないため、コンパイルエラーになります。
サンプルコード
#include <iostream>
using namespace std;
class MyBaseClass {
protected:
int x;
public:
MyBaseClass() {
x = 20;
}
friend void display();
};
class MyDerivedClass : public MyBaseClass {
private:
int y;
public:
MyDerivedClass() {
x = 40;
}
};
void display() {
MyDerivedClass derived;
cout << "The value of private member of Base class is: " << derived.x << endl;
cout << "The value of private member of Derived class is: " << derived.y << endl;
}
main() {
display();
}実行結果(エラー)
[Error] 'int MyDerivedClass::y' is private [Error] within this context
解説
このコードでは、display()関数はMyBaseClassに対してfriend宣言されているため、基底クラスのprotectedメンバーであるxにはアクセスできます。しかし、派生クラスMyDerivedClassのprivateメンバーであるyへのアクセスは許可されていません。
これは、C++の設計思想によるものです。friend関係は特定のクラスとの間で明示的に結ばれる特権的なアクセス権であり、継承階層に自動的に伝播させると、カプセル化が意図せず破られる恐れがあるためです。
対処法
もし派生クラスのprivateメンバーにもアクセスしたい場合は、以下のような方法があります。
- 派生クラス側でも同じ関数をfriendとして宣言する
- アクセス用のpublicなメンバ関数(getterなど)を用意する
class MyDerivedClass : public MyBaseClass {
private:
int y;
public:
MyDerivedClass() {
x = 40;
y = 50;
}
friend void display(); // 派生クラスでもfriend宣言する
};このように、必要なクラスごとに個別にfriend宣言を行うことで、意図したアクセス制御を実現できます。friendの使用は最小限にとどめ、カプセル化を損なわないよう注意して設計することが推奨されます。
-
【C++入門】多重継承の基本と実装方法をわかりやすく解説
多重継承(Multiple Inheritance)とは多重継承とは、ひとつのクラスが複数の基底クラス(親クラス)から派生する仕組みのことです。多重継承を利用することで、派生クラスは複数の基底クラスが持つ機能やデータメンバをまとめて引き継ぐことができます。これはC++に代表されるオブジェクト指向プログラミング言語における重要な機能のひとつです。多重継承の構造を表した図が以下になります。C++で多重継承を実装するサンプルプログラムここでは、C++で多重継承を実装したサンプルプログラムを紹介します。クラスCが、クラスAとクラスBの2つのクラスを同時に継承する例です。サンプルコード#include
-
C++のフレンド関数とフレンドクラスの基本を解説
C++におけるフレンド関数(friend function)とは、クラスのスコープ外で定義される関数でありながら、そのクラスのすべてのprivateメンバーおよびprotectedメンバーにアクセスする権限を持つ特別な関数です。フレンド関数のプロトタイプ(宣言)はクラス定義の中に記述しますが、あくまで「友達」として扱われるだけであり、クラスのメンバー関数にはなりません。この点は重要なポイントです。フレンドとして指定できるものフレンドとして宣言できるのは、以下のようなものです。通常の関数関数テンプレート他のクラスのメンバー関数クラス全体(この場合、そのクラスのすべてのメンバーがフレンドになります