C++ 类访问修饰符
C++のオブジェクト指向プログラミング(OOP)において、データのカプセル化(Encapsulation)は中核的な概念の一つです。簡単に言えば、データを「隠して」、必要なインターフェースだけを外部に公開し、データの安全性を確保することです。
誰がこれらのデータを見られるかを制御するために、C++は3つのキーワードを提供しています。それは、访问修饰符:
public(公有)private(私有)protected(受保护)
理解を容易にするために、私たちは一つの...クラス(Class)をあなたの家と想像してください:
| 修饰符 | 现实类比 | 誰がアクセスできるか? | 典型用途 |
|---|---|---|---|
| public | 客厅/大门 | 所有人(クラス内部、サブクラス、外部コード) | 外部に公開するインターフェース関数(API)。 |
| protected | 卧室 | あなたとあなたの子供(クラス内部、サブクラス) | 家族(継承体系)内部だけで使用できるデータ。 |
| private | 保险箱 | 只有你自己(このクラスの内部のみ) | 中核データ、勝手に変更されたくない変数。 |
注意:何も修飾子を書かない場合、C++クラスメンバーはデフォルトは
private(私有)の。
公有(public)メンバー
公有メンバーはプログラム内のどこからでもアクセスでき、メンバー関数による読み書きを必要としません。例は次のとおりです:
实例
上記のコードをコンパイルして実行すると、次の結果が得られます。
Length of line : 6 Length of line : 10
私有(private)メンバー
プライベートメンバーはクラス外部に対して完全に閉鎖されており、外部コードは読み取り・変更・呼び出しができず、派生クラスも直接アクセスする権利がありません。操作できるのは、クラス自身のメンバー関数とフレンド権限を付与されたエンティティだけです。
クラス内でアクセス指定子を一切使用しない場合、メンバーはデフォルトでプライベートになります。下の例のように、width は自動的にプライベート領域に入り、明示的に指定されていないメンバーはすべてプライベートとして扱われることを示しています:
实例
実際の操作では、通常はプライベート領域にデータを定義し、パブリック領域に関連する関数を定義します。これにより、クラスの外部からもこれらの関数を呼び出すことができます。以下に示すとおりです。
实例
上記のコードをコンパイルして実行すると、次の結果が得られます。
Length of box : 10 Width of box : 10
protected(保護)メンバー
protectedの存在は主に〜のためです继承。
- 継承がない場合、それは...と
private同じです(外部からは見えません)。 - もし継承があれば、サブクラス(派生クラス)は親クラスの...にアクセスできます。
protected成员、しかしアクセスできないprivate成员。
次の章では、派生クラスと継承の知識を学びます。さて、以下の例では、私たちは親クラスから...Boxサブクラスを派生させたsmallBox。
以下の例は前の例と似ています。ここでは...widthメンバーは派生クラス smallBox の任意のメンバー関数からアクセスできます。
实例
上記のコードをコンパイルして実行すると、次の結果が得られます。
Width of box : 5
継承におけるアクセス権限の変化
サブクラスを定義するとき(例:class B : public A)、コロンの後のpublicこれもアクセス修飾子の一種であり、...を決定します。親クラスのメンバーが子クラスでどのような形で「現れる」のか。
これは複雑に見えますが、覚えるのはこれだけです。降级原则:
継承方式は、親クラスのメンバーが子クラスで持つ最高権限を決定します。
継承方式がメンバーの元の権限より厳しい場合、メンバーの権限は継承方式のレベルまで「降格」されます。
权限变化表
| 基底クラスのメンバーの元の権限 | public 继承(最常用) | protected 继承 | private 继承 |
|---|---|---|---|
| public | 保持 public | protected に降格 | private に降格 |
| protected | 保持 protected | 保持 protected | private に降格 |
| private | 不可访问 | 不可访问 | 不可访问 |
注:アクセス不可とは、子クラスのコードがその変数を直接使用できないことを指しますが、変数自体はメモリ内に存在し続けます。
総合デモコード
明確に示すために、変数の名前を次のように変更します:pub_var(公有),pro_var(保護)、pri_var(私有)。
实例
using namespace std;
class Parent {
public:
int pub_var;
protected:
int pro_var;
private:
int pri_var; // 只有 Parent 自己能动
public:
Parent() { pub_var = 1; pro_var = 2; pri_var = 3; }
};
// 1. 公有继承(Public Inheritance)- 最常见,原汁原味
class ChildA : public Parent {
public:
void test() {
cout << pub_var << endl; // OK
cout << pro_var << endl; // OK
// cout << pri_var << endl; // 错误!父类私有成员不可见
}
};
// 2. protected継承(Protected Inheritance)- すべてがprotectedになる
class ChildB : protected Parent {
public:
void test() {
cout << pub_var << endl; // OK、しかし ChildB から見ると、それは protected です。
cout << pro_var << endl; // OK
}
};
// 3. プライベート継承(Private Inheritance)- すべてがプライベートになる
class ChildC : private Parent {
public:
void test() {
cout << pub_var << endl; // OK、ただし ChildC から見れば、それは private です
cout << pro_var << endl; // OK、ただし ChildC から見れば、それは private です
}
};
int main() {
ChildA a;
cout << a.pub_var << endl; // OK,外部可以访问
// cout << a.pro_var << endl; // 错误,外部不可访问 protected
ChildB b;
// cout << b.pub_var << endl; // エラー!protected 継承のため、pub_var は外部では protected になる
ChildC c;
// cout << c.pub_var << endl; // エラー!これは private 継承のため、pub_var は外部で private になります。
return 0;
}
总结
- Public:誰でも使えます。インターフェース(API)として使います。
- Private:自分だけが使えます。データを保存するために使います(デフォルトの安全オプション)。
- Protected:家族(継承チェーン)だけが使えます。子クラスに裏口を残すために使います。
继承:
- Public 继承:親クラスの属性はそのまま保持されます(最も一般的)。
- Private/Protected 继承:親クラスのメンバーの権限を厳しくします。通常、特別な実装シナリオで使用されます。