Skip to main content

10-2 存取控制——public 與 private

一、class 裡的東西,不是誰都可以動的

先看一個銀行帳戶的例子。

#include <iostream>

using namespace std;

class BankAccount {
public:
    string owner;
    int balance;
};

int main() {
    BankAccount acc;
    acc.owner   = "小明";
    acc.balance = 1000;

    acc.balance = -99999;   // 沒有任何阻擋,帳戶餘額變成負的!

    cout << acc.balance << endl;
}

這是因為我們之前在 class 裡用了 publicpublic: 這個存取修飾詞。 public 的意思就是「公開的」,誰想看、誰想改都可以。

用 privateprivate: 將存取限制改為「私有的」看看差別。

#include <iostream>

using namespace std;

class BankAccount {
private:
    string owner;
    int balance;
};

int main() {
    BankAccount acc;
    acc.owner   = "小明";
    acc.balance = 1000;

    acc.balance = -99999;   // 沒有任何阻擋,帳戶餘額變成負的!

    cout << acc.balance << endl;
}

修改之後,連編譯都失敗了,連編譯都失敗,出現了大量如下的錯誤訊息。

因為使用 privte 修飾的屬性和成員函數,在該 class 之外(第 5~9 行之外)都無法存取,在編譯時就攔下了不合法的存取。

main.cpp:13:9: error: 'std::string BankAccount::owner' is private within this context
   13 |     acc.owner   = "小明";
      |         ^~~~~
main.cpp:7:12: note: declared private here
    7 |     string owner;
      |            ^~~~~
main.cpp:14:9: error: 'int BankAccount::balance' is private within this context
   14 |     acc.balance = 1000;
      |         ^~~~~~~
main.cpp:8:9: note: declared private here
    8 |     int balance;
      |         ^~~~~~~
main.cpp:16:9: error: 'int BankAccount::balance' is private within this context
   16 |     acc.balance = -99999;   // 沒有任何阻擋,帳戶餘額變成負的!
      |         ^~~~~~~
main.cpp:8:9: note: declared private here
    8 |     int balance;
      |         ^~~~~~~
main.cpp:18:17: error: 'int BankAccount::balance' is private within this context
   18 |     cout << acc.balance << endl;
      |                 ^~~~~~~
main.cpp:8:9: note: declared private here
    8 |     int balance;
      |         ^~~~~~~

二、提供外界有限的操作

設成 public 太危險,設成 private 又動不了,怎麼辦呢?

我們可以

    把內部屬性設為 private 用 public 開放幾個成員函數,給外界有限能力操作內部屬性
    #include <iostream>
    
    using namespace std;
    
    class BankAccount {
    private:
        string owner;
        int balance;    // 外部無法直接存取
    
    public:
        // 以下成員函數,開放給外部使用,提供存取 balance 的管道
        bool withdraw(int amount) {
            if (amount > balance) {
                cout << "餘額不足!" << endl;
                return false;
            }
            balance -= amount;
            return true;
        }
    
        void deposit(int amount) {
            if (amount <= 0) {
                cout << "存款金額必須大於 0!" << endl;
                return;
            }
            balance += amount;
        }
    
        int getBalance() { return balance; }
    };
    
    int main()
    {
        BankAccount account;
        account.deposit(1000);  // 存款 1000 元
        cout << "目前餘額: " << account.getBalance() << " 元" << endl;
    
        if (account.withdraw(500)) {  // 提款 500 元
            cout << "提款成功!" << endl;
        }
        cout << "目前餘額: " << account.getBalance() << " 元" << endl;
    
        if (!account.withdraw(600)) {  // 嘗試提款 600 元,應該會失敗
            cout << "提款失敗!" << endl;
        }
        cout << "目前餘額: " << account.getBalance() << " 元" << endl;
    
        return 0;
    }
    
    

    現在外部程式只能透過 withdraw() 和 deposit() 來改變餘額,透過 getBalance() 來取得餘額,非法操作會被擋下來。

    public、private 存取修飾詞的作用範圍

    class Example {
    // 這裡沒寫 → class 預設是 private
        int secret;
    
    public:
        int visible;
        void doSomething() { }
    
    private:
        int alsoSecret;
    };
    

    public: 和 private: 後面的所有成員,都套用該修飾子,直到遇到下一個修飾子為止。