C++ public/protected/private継承の違いを徹底解説
C++ public、protected、private継承
このチュートリアルでは、実践的な例を通じてC++でのpublic、protected、private継承の使い方を学びます。
C++継承では、基底クラスから子クラスを異なるアクセスモードで派生させられます。例えば:
class Base { .... ... .... };
class Derived : public Base { .... ... .... };
コードclass Derived : public Baseのpublicキーワードに注目してください。これはpublicモードで派生クラスを作成したことを意味します。また、protectedやprivateモードで派生させることもできます。
これら3つのキーワード(public、protected、private)はC++継承におけるアクセス指定子と呼ばれます。
C++におけるpublic、protected、private継承
public、protected、private継承には以下の特徴があります:
- public継承では、基底クラスの
publicメンバが派生クラスでpublic、protectedメンバが派生クラスでprotectedのままになります。 - protected継承では、基底クラスの
publicとprotectedメンバが派生クラスでprotectedになります。 - private継承では、基底クラスの
publicとprotectedメンバが派生クラスでprivateになります。
注意: 基底クラスのprivateメンバは派生クラスからアクセスできません。
class Base {
public:
int x;
protected:
int y;
private:
int z;
};
class PublicDerived: public Base {
// xはpublic
// yはprotected
// zはPublicDerivedからアクセス不可
};
class ProtectedDerived: protected Base {
// xはprotected
// yはprotected
// zはProtectedDerivedからアクセス不可
};
class PrivateDerived: private Base {
// xはprivate
// yはprivate
// zはPrivateDerivedからアクセス不可
}
例1: C++ public継承
// public継承の動作を示すC++プログラム
#include <iostream>
using namespace std;
class Base {
private:
int pvt = 1;
protected:
int prot = 2;
public:
int pub = 3;
// privateメンバにアクセスする関数
int getPVT() { return pvt; }
};
class PublicDerived : public Base {
public:
// 基底クラスからprotectedメンバにアクセスする関数
int getProt() { return prot; }
};
int main() {
PublicDerived object1;
cout << "Private = " << object1.getPVT() << endl;
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.pub << endl;
return 0;
}
出力
Private = 1 Protected = 2 Public = 3
ここでは、PublicDerivedをBaseからpublicモードで派生させています。
結果としてPublicDerivedでは:
- protはprotectedとして継承されます。
- pubと
getPVT()はpublicとして継承されます。 - pvtは
Baseでprivateなのでアクセス不可です。
privateとprotectedメンバはmain()から直接アクセスできないため、それらにアクセスするためのpublic関数getPVT()とgetProt()を作成する必要があります:
// エラー: メンバ "Base::pvt" はアクセス不可
cout << "Private = " << object1.pvt;
// エラー: メンバ "Base::prot" はアクセス不可
cout << "Protected = " << object1.prot;
getPVT()関数はBase内で定義されていますが、getProt()関数はPublicDerived内で定義されています。
これはpvtがBaseでprivateであり、PublicDerivedからアクセスできないためです。
一方、protはpublic継承によりPublicDerivedからアクセス可能です。そのためgetProt()はPublicDerived内からprotected変数にアクセスできます。
public継承でのアクセス可能性
| アクセス可能性 | privateメンバ | protectedメンバ | publicメンバ |
|---|---|---|---|
| 基底クラス | Yes | Yes | Yes |
| 派生クラス | No | Yes | Yes |
例2: C++ protected継承
// protected継承の動作を示すC++プログラム
#include <iostream>
using namespace std;
class Base {
private:
int pvt = 1;
protected:
int prot = 2;
public:
int pub = 3;
int getPVT() { return pvt; }
};
class ProtectedDerived : protected Base {
public:
int getProt() { return prot; }
int getPub() { return pub; }
};
int main() {
ProtectedDerived object1;
cout << "Private cannot be accessed." << endl;
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.getPub() << endl;
return 0;
}
出力
Private cannot be accessed. Protected = 2 Public = 3
ここでは、ProtectedDerivedをBaseからprotectedモードで派生させています。
結果としてProtectedDerivedでは:
- prot、pubと
getPVT()はprotectedとして継承されます。 pvtはBaseでprivateなのでアクセス不可です。
ご存知の通り、protectedメンバはクラス外部から直接アクセスできません。その結果、ProtectedDerivedからgetPVT()を使うことはできません。
そのためpub変数にアクセスするためにProtectedDerivedでgetPub()関数を作成する必要があります。
// エラー: メンバ "Base::getPVT()" はアクセス不可
cout << "Private = " << object1.getPVT();
// エラー: メンバ "Base::pub" はアクセス不可
cout << "Public = " << object1.pub;
protected継承でのアクセス可能性
| アクセス可能性 | privateメンバ | protectedメンバ | publicメンバ |
|---|---|---|---|
| 基底クラス | Yes | Yes | Yes |
| 派生クラス | No | Yes | Yes(protected変数として継承) |
例3: C++ private継承
// private継承の動作を示すC++プログラム
#include <iostream>
using namespace std;
class Base {
private:
int pvt = 1;
protected:
int prot = 2;
public:
int pub = 3;
int getPVT() { return pvt; }
};
class PrivateDerived : private Base {
public:
int getProt() { return prot; }
int getPub() { return pub; }
};
int main() {
PrivateDerived object1;
cout << "Private cannot be accessed." << endl;
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.getPub() << endl;
return 0;
}
出力
Private cannot be accessed. Protected = 2 Public = 3
ここでは、PrivateDerivedをBaseからprivateモードで派生させています。
結果としてPrivateDerivedでは:
- prot、
pubとgetPVT()はprivateとして継承されます。 - pvtは
Baseでprivateなのでアクセス不可です。
ご存知の通り、privateメンバはクラス外部から直接アクセスできません。その結果、PrivateDerivedからgetPVT()を使うことはできません。
そのためpub変数にアクセスするためにPrivateDerivedでgetPub()関数を作成する必要があります。
// エラー: メンバ "Base::getPVT()" はアクセス不可
cout << "Private = " << object1.getPVT();
// エラー: メンバ "Base::pub" はアクセス不可
cout << "Public = " << object1.pub;
private継承でのアクセス可能性
| アクセス可能性 | privateメンバ | protectedメンバ | publicメンバ |
|---|---|---|---|
| 基底クラス | Yes | Yes | Yes |
| 派生クラス | No | Yes(private変数として継承) | Yes(private変数として継承) |
C言語
- C++構造体とクラス:組み込み開発者のための実践ガイド
- Sigfox、プライベートエリアネットワーク発表、測位強化、IoTソリューション拡大
- 最適なクラウド戦略の選び方:パブリック、プライベート、ハイブリッドを徹底解説
- パブリッククラウド:メリット、リスク、重要な検討事項
- プライベートクラウド:メリット、デメリット、ビジネスデータを守る仕組み
- C++変数・リテラル・定数完全ガイド:基礎から実践まで
- C++クラスとオブジェクト完全ガイド:オブジェクト指向プログラミングの実践
- C++メモリ管理の極意:newとdeleteのエキスパート活用法
- C++フレンド関数とフレンドクラス:アクセス制御のマスター
- C++演算子を徹底解説:種類、例、サンプルプログラム付き
- C++ structとclassの違い:構文、特徴、使い分けのベストプラクティス