Menu
Coddy logo textTech

C++のアクセス指定子

CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 34/104。

C++ には、クラスの member に誰が access できるかを制御する 3 つのaccess specifierがあります:publicprotectedprivate。これらはカプセル化の基盤を形成します。

class Account {
public:
    std::string ownerName;      // どこからでもアクセス可能
    
protected:
    double interestRate;        // このクラスおよび派生クラスからアクセス可能
    
private:
    double balance;             // このクラス内でのみアクセス可能
};

Publicメンバーは、クラス内、派生クラス、外部コードなど、どこからでもアクセスできます。Privateメンバーは最も制限が厳しく、クラス自体の内部からのみアクセスできます。Protectedはその中間に位置します。外部からはprivateのように動作しますが、派生クラスはこれらのメンバーにアクセスできます。

class Account {
private:
    double balance;
    
public:
    Account() : balance(0) {}
    
    void deposit(double amount) {
        balance += amount;    // OK - クラスの内部
    }
};

int main() {
    Account acc;
    acc.deposit(100);         // OK - deposit は public
    // acc.balance = 500;     // ERROR - balance は private
}

デフォルトでは、指定子が与えられていない場合、class 内のすべての member は private です。これにより、何を公開すべきかを明示的に決めるよう促されます。一般的には、データ member を private にし、それらと安全にやり取りするための public method を提供します。

challenge icon

チャレンジ

簡単

誰が何にアクセスできるかをaccess specifierが制御する仕組みを示す、シンプルな従業員管理システムを作成しましょう。データの一部を完全にprivateにし、一部を派生クラスからアクセス可能にし、残りを全員に公開するclassを作成します。

コードを整理するために、2つのファイルを作成します。

  • Employee.h:3種類すべてのaccess specifierを使用して、データを適切に保護するEmployee classをDefineします。
    • Public:従業員のname(string)。これはどこからでもaccessできます
    • Protected:従業員のdepartment(string):class内およびderived classesからaccessできますが、外部からはaccessできません
    • Private:従業員のsalary(double):class自体の内部からのみaccessできます
    • name、department、salaryを受け取り、3つのmemberすべてを初期化するConstructor
    • privateなsalaryの値を返すpublic method getSalary()
    • protectedなdepartmentの値を返すpublic method getDepartment()
    • amountが正の場合に限り、指定されたamountだけsalaryを増やすpublic method giveRaise(double amount)
    • 従業員のinformationを次のFormatで出力するpublic method displayInfo()"Name: <name>, Department: <department>, Salary: $<salary>"
  • main.cpp:Employee objectとやり取りしながら、access specifierの動作を示します。従業員のname、department、salaryをinputから(3つの別々の行で)読み込み、次の処理を行います。
    • inputの値を使ってEmployeeをCreateします
    • public memberに直接accessして従業員のnameを出力します:"Direct access - Name: <name>"
    • getterを使用してdepartmentを出力します:"Via getter - Department: <department>"
    • getterを使用してsalaryを出力します:"Via getter - Salary: $<salary>"
    • 従業員に5000.0の昇給をGiveします
    • "After raise:"を出力します
    • 更新されたinformationを表示するためにdisplayInfo()をCallします

すべてのsalaryの値を小数点以下2桁でFormatするには、<iomanip>std::fixedstd::setprecision(2)を使用します。salaryのinputはstd::stod()を使用してstringからdoubleに変換します。

ここでの重要なポイントは、mainからnameには直接accessできますが、departmentsalaryには直接accessできないことです。publicなgetter methodを使用する必要があります。これがカプセル化の実例です。classが、そのdataにどのようにaccessし、変更できるかを制御します。

自分で試してみよう

#include <iostream>
#include <string>
#include <iomanip>
#include "Employee.h"

using namespace std;

int main() {
    // 入力を読み取る
    string name;
    string department;
    string salaryStr;
    
    getline(cin, name);
    getline(cin, department);
    getline(cin, salaryStr);
    double salary = stod(salaryStr);
    
    // 給与出力の精度を設定する
    cout << fixed << setprecision(2);
    
    // TODO: 入力値でEmployeeオブジェクトを作成する
    
    // TODO: パブリックメンバーに直接アクセスして従業員の名前を出力する
    // Format: "Direct access - Name: <name>"
    
    // TODO: ゲッターメソッドを使用して部署を出力する
    // Format: "Via getter - Department: <department>"
    
    // TODO: ゲッターメソッドを使用して給与を出力する
    // Format: "Via getter - Salary: $<salary>"
    
    // TODO: 従業員に5000.0の昇給を与える
    
    // TODO: "After raise:"を出力する
    
    // TODO: displayInfo()を呼び出して更新された情報を表示する
    
    return 0;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: C++オンラインコンパイラ