Series: C++
cpp
286 lines
· Updated 2026-04-03
access_control.cpp
C++/Part2_物件導向/Ch08_類別與物件/access_control.cpp
// ============================================================
// Ch08 — 存取控制、static 成員
// 編譯:g++ -std=c++17 -Wall -o access_control access_control.cpp
// ============================================================
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
// ============================================================
// 1. Student — static 成員變數追蹤物件數量
// ============================================================
class Student {
private:
std::string name;
int score;
static int totalCount; // 靜態成員變數 — 所有物件共享
public:
Student(const std::string& name, int score)
: name(name), score(score) {
++totalCount;
std::cout << " [建立] " << name
<< "(目前學生數: " << totalCount << ")" << std::endl;
}
~Student() {
--totalCount;
std::cout << " [銷毀] " << name
<< "(剩餘學生數: " << totalCount << ")" << std::endl;
}
// const 成員函式
const std::string& getName() const { return name; }
int getScore() const { return score; }
void print() const {
std::cout << " " << name << ": " << score << " 分" << std::endl;
}
// static 成員函式 — 不需物件即可呼叫
static int getTotalCount() {
return totalCount;
}
};
// static 成員變數必須在類別外定義
int Student::totalCount = 0;
// ============================================================
// 2. Circle — 展示封裝與資料驗證
// ============================================================
class Circle {
private:
double radius;
static constexpr double PI = 3.14159265358979;
static int instanceCount;
public:
explicit Circle(double r = 1.0) : radius(r > 0 ? r : 1.0) {
++instanceCount;
}
~Circle() {
--instanceCount;
}
// Getter
double getRadius() const { return radius; }
// Setter — 帶驗證
void setRadius(double r) {
if (r > 0) {
radius = r;
} else {
std::cout << " ⚠ 半徑必須大於 0,維持原值 "
<< radius << std::endl;
}
}
// const 成員函式
double area() const { return PI * radius * radius; }
double circumference() const { return 2.0 * PI * radius; }
double diameter() const { return 2.0 * radius; }
void print() const {
std::cout << " Circle(r=" << radius
<< ") → 面積=" << area()
<< ", 周長=" << circumference() << std::endl;
}
// static 成員函式
static int getInstanceCount() { return instanceCount; }
static double getPI() { return PI; }
};
int Circle::instanceCount = 0;
// ============================================================
// 3. AccessDemo — 展示 public / private / protected
// ============================================================
class AccessDemo {
public:
int publicVar = 1;
void publicMethod() const {
std::cout << " publicMethod() — 任何地方都能呼叫" << std::endl;
privateMethod(); // 類別內部可以呼叫 private 方法
}
protected:
int protectedVar = 2;
void protectedMethod() const {
std::cout << " protectedMethod() — 類別內部及衍生類別可呼叫" << std::endl;
}
private:
int privateVar = 3;
void privateMethod() const {
std::cout << " privateMethod() — 只有類別內部可呼叫"
<< "(privateVar=" << privateVar << ")" << std::endl;
}
};
// 衍生類別示範 protected 的可見性
class DerivedDemo : public AccessDemo {
public:
void test() const {
std::cout << " [衍生類別]" << std::endl;
std::cout << " publicVar = " << publicVar << std::endl;
std::cout << " protectedVar = " << protectedVar << std::endl;
// std::cout << privateVar; // 編譯錯誤!private 不可存取
publicMethod();
protectedMethod();
// privateMethod(); // 編譯錯誤!
}
};
// ============================================================
// 4. Config — static 成員函式實現全域設定
// ============================================================
class Config {
private:
static std::string appName;
static int maxConnections;
static bool debugMode;
public:
// 禁止建立實例 — 純工具類別
Config() = delete;
static void setAppName(const std::string& name) { appName = name; }
static void setMaxConnections(int max) {
if (max > 0 && max <= 1000) maxConnections = max;
}
static void setDebugMode(bool enabled) { debugMode = enabled; }
static const std::string& getAppName() { return appName; }
static int getMaxConnections() { return maxConnections; }
static bool isDebugMode() { return debugMode; }
static void printAll() {
std::cout << " 應用程式名稱: " << appName << std::endl;
std::cout << " 最大連線數: " << maxConnections << std::endl;
std::cout << " 除錯模式: " << (debugMode ? "開啟" : "關閉") << std::endl;
}
};
// static 成員定義
std::string Config::appName = "MyApp";
int Config::maxConnections = 100;
bool Config::debugMode = false;
// ============================================================
// main
// ============================================================
int main() {
std::cout << "========================================" << std::endl;
std::cout << " Ch08 存取控制與 static 成員" << std::endl;
std::cout << "========================================\n" << std::endl;
// ------ 1. Student — static 計數 ------
std::cout << "【1】Student — static 成員追蹤物件數量\n" << std::endl;
std::cout << " 初始學生數: " << Student::getTotalCount() << "\n" << std::endl;
{
Student s1("小明", 90);
Student s2("小華", 85);
Student s3("小美", 92);
std::cout << "\n 區塊內學生數: " << Student::getTotalCount() << std::endl;
std::cout << std::endl;
s1.print();
s2.print();
s3.print();
std::cout << std::endl;
}
// s1, s2, s3 離開作用域,解構子被呼叫
std::cout << "\n 區塊外學生數: " << Student::getTotalCount() << "\n" << std::endl;
// ------ 2. Circle — 封裝與驗證 ------
std::cout << "【2】Circle — 封裝、驗證、static\n" << std::endl;
Circle c1(5.0);
Circle c2(3.0);
Circle c3; // 使用預設半徑 1.0
c1.print();
c2.print();
c3.print();
std::cout << std::endl;
std::cout << " Circle 實例數: " << Circle::getInstanceCount() << std::endl;
std::cout << " PI = " << Circle::getPI() << std::endl;
std::cout << std::endl;
// 測試驗證
std::cout << " 測試 setter 驗證:" << std::endl;
c3.setRadius(10.0);
c3.print();
c3.setRadius(-5.0); // 無效值
c3.print();
std::cout << std::endl;
// ------ 3. 存取層級 ------
std::cout << "【3】存取修飾詞示範\n" << std::endl;
AccessDemo base;
std::cout << " [基礎類別 — 外部存取]" << std::endl;
std::cout << " publicVar = " << base.publicVar << std::endl;
base.publicMethod();
// base.protectedMethod(); // ✗ 外部不可存取 protected
// base.privateMethod(); // ✗ 外部不可存取 private
std::cout << std::endl;
DerivedDemo derived;
std::cout << " [衍生類別存取測試]" << std::endl;
derived.test();
std::cout << std::endl;
// ------ 4. Config — 純 static 類別 ------
std::cout << "【4】Config — 純 static 工具類別\n" << std::endl;
std::cout << " 預設設定:" << std::endl;
Config::printAll();
std::cout << std::endl;
Config::setAppName("教學系統");
Config::setMaxConnections(50);
Config::setDebugMode(true);
std::cout << " 修改後設定:" << std::endl;
Config::printAll();
std::cout << std::endl;
// ------ 5. 封裝的實際好處 ------
std::cout << "【5】封裝的好處 — 對比\n" << std::endl;
std::cout << " ❌ 沒有封裝(struct 直接存取):" << std::endl;
std::cout << " circle.radius = -10; // 不合法但無法阻止" << std::endl;
std::cout << std::endl;
std::cout << " ✓ 有封裝(class + setter):" << std::endl;
std::cout << " circle.setRadius(-10); // setter 會拒絕不合法值" << std::endl;
std::cout << std::endl;
std::cout << " 封裝三大好處:" << std::endl;
std::cout << " 1. 資料驗證 — 確保物件狀態始終合法" << std::endl;
std::cout << " 2. 隱藏實作 — 外部不依賴內部結構" << std::endl;
std::cout << " 3. 維護彈性 — 修改內部不影響使用者" << std::endl;
std::cout << "\n========================================" << std::endl;
std::cout << " 範例結束" << std::endl;
std::cout << "========================================" << std::endl;
return 0;
}
Related articles
C++
c
Updated 2026-07-21
deviceAlpha.h
deviceAlpha.h — c source code from the C++ learning materials (C++/Mavis_Homework/FinalProject/deviceAlpha.h).
Read article →
C++
c
Updated 2026-07-21
finalproject.c
finalproject.c — c source code from the C++ learning materials (C++/Mavis_Homework/FinalProject/finalproject.c).
Read article →
C++
cpp
Updated 2026-07-21
finalproject.cpp
finalproject.cpp — cpp source code from the C++ learning materials (C++/Mavis_Homework/FinalProject/finalproject.cpp).
Read article →
C++
c
Updated 2026-07-21
deviceAlpha.h
deviceAlpha.h — c source code from the C++ learning materials (C++/Mavis_Homework/Lab8/deviceAlpha.h).
Read article →
C++
c
Updated 2026-07-21
lab8.c
lab8.c — c source code from the C++ learning materials (C++/Mavis_Homework/Lab8/lab8.c).
Read article →
C++
cpp
Updated 2026-07-21
lab8.cpp
lab8.cpp — cpp source code from the C++ learning materials (C++/Mavis_Homework/Lab8/lab8.cpp).
Read article →