C++ 类访问修饰符

C++ クラス & オブジェクト

C++のオブジェクト指向プログラミング(OOP)において、データのカプセル化(Encapsulation)は中核的な概念の一つです。簡単に言えば、データを「隠して」、必要なインターフェースだけを外部に公開し、データの安全性を確保することです。

誰がこれらのデータを見られるかを制御するために、C++は3つのキーワードを提供しています。それは、访问修饰符:

  • public(公有)
  • private(私有)
  • protected(受保护)
class Base { public: //公有成员 protected: // 受保护成员 private: // 私有成员 };

理解を容易にするために、私たちは一つの...クラス(Class)をあなたの家と想像してください:

修饰符 现实类比 誰がアクセスできるか? 典型用途
public 客厅/大门 所有人(クラス内部、サブクラス、外部コード) 外部に公開するインターフェース関数(API)。
protected 卧室 あなたとあなたの子供(クラス内部、サブクラス) 家族(継承体系)内部だけで使用できるデータ。
private 保险箱 只有你自己(このクラスの内部のみ) 中核データ、勝手に変更されたくない変数。

注意:何も修飾子を書かない場合、C++クラスメンバーはデフォルトはprivate(私有)の。

公有(public)メンバー

公有メンバーはプログラム内のどこからでもアクセスでき、メンバー関数による読み書きを必要としません。例は次のとおりです:

实例

#include <iostream> using namespace std; class Line { public: double length; void setLength( double len ); double getLength( void ); }; // 成员函数定义 double Line::getLength(void) { return length ; } void Line::setLength( double len ) { length = len; } // プログラムのメイン関数 int main( ) { Line line; // 设置长度 line.setLength(6.0); cout << "Length of line : " << line.getLength() <<endl; // 不使用成员函数设置长度 line.length = 10.0; // OK: length は public なので cout << "Length of line : " << line.length <<endl; return 0; }

上記のコードをコンパイルして実行すると、次の結果が得られます。

Length of line : 6
Length of line : 10

私有(private)メンバー

プライベートメンバーはクラス外部に対して完全に閉鎖されており、外部コードは読み取り・変更・呼び出しができず、派生クラスも直接アクセスする権利がありません。操作できるのは、クラス自身のメンバー関数とフレンド権限を付与されたエンティティだけです。

クラス内でアクセス指定子を一切使用しない場合、メンバーはデフォルトでプライベートになります。下の例のように、width は自動的にプライベート領域に入り、明示的に指定されていないメンバーはすべてプライベートとして扱われることを示しています:

实例

class Box { double width; public: double length; void setWidth( double wid ); double getWidth( void ); };

実際の操作では、通常はプライベート領域にデータを定義し、パブリック領域に関連する関数を定義します。これにより、クラスの外部からもこれらの関数を呼び出すことができます。以下に示すとおりです。

实例

#include <iostream> using namespace std; class Box { public: double length; void setWidth( double wid ); double getWidth( void ); private: double width; }; // 成员函数定义 double Box::getWidth(void) { return width ; } void Box::setWidth( double wid ) { width = wid; } // プログラムのメイン関数 int main( ) { Box box; // 不使用成员函数设置长度 box.length = 10.0; // OK: length は public なので cout << "Length of box : " << box.length <<endl; // 不使用成员函数设置宽度 // box.width = 10.0; // Error: width は private であるため box.setWidth(10.0); // 使用成员函数设置宽度 cout << "Width of box : " << box.getWidth() <<endl; return 0; }

上記のコードをコンパイルして実行すると、次の結果が得られます。

Length of box : 10
Width of box : 10

protected(保護)メンバー

protectedの存在は主に〜のためです继承。

  • 継承がない場合、それは...とprivate同じです(外部からは見えません)。
  • もし継承があれば、サブクラス(派生クラス)は親クラスの...にアクセスできます。protected成员、しかしアクセスできないprivate成员。

次の章では、派生クラスと継承の知識を学びます。さて、以下の例では、私たちは親クラスから...Boxサブクラスを派生させたsmallBox。

以下の例は前の例と似ています。ここでは...widthメンバーは派生クラス smallBox の任意のメンバー関数からアクセスできます。

实例

#include <iostream> using namespace std; class Box { protected: double width; }; class SmallBox:Box // SmallBox は派生クラス { public: void setSmallWidth( double wid ); double getSmallWidth( void ); }; // 派生クラスのメンバー関数 double SmallBox::getSmallWidth(void) { return width ; } void SmallBox::setSmallWidth( double wid ) { width = wid; } // プログラムのメイン関数 int main( ) { SmallBox box; // 使用成员函数设置宽度 box.setSmallWidth(5.0); cout << "Width of box : "<< box.getSmallWidth() << endl; return 0; }

上記のコードをコンパイルして実行すると、次の結果が得られます。

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(私有)。

实例

#include <iostream>
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 继承:親クラスのメンバーの権限を厳しくします。通常、特別な実装シナリオで使用されます。

C++ クラス & オブジェクト

其他扩展