// A.cpp
double tempValue = 0.0; // 全域變數(非 static)
// B.cpp
extern double tempValue; // 宣告外部連結
void B::SomeFunction() {
tempValue = 42.0; // 直接讀寫
}
// A.h
class A {
public:
static double GetTempValue();
static void SetTempValue(double val);
private:
static double s_tempValue;
};
// A.cpp
double A::s_tempValue = 0.0;
double A::GetTempValue() { return s_tempValue; }
void A::SetTempValue(double val) { s_tempValue = val; }
// B.cpp
#include "A.h"
void B::UseValue() {
double v = A::GetTempValue();
}
// A.h
class A {
public:
double pubValue = 0.0;
};
// B.h
class B {
public:
void SetA(A* aPtr) { m_a = aPtr; }
void UsePubValue();
private:
A* m_a = nullptr;
};
// B.cpp
void B::UsePubValue() {
if (m_a) {
double v = m_a->pubValue; // 透過物件存取
}
}
// 使用端
A aObj;
B bObj;
bObj.SetA(&aObj);
bObj.UsePubValue();
// A.h
class A {
public:
static double pubValue; // 宣告
static double GetPubValue() { return pubValue; }
};
// A.cpp
double A::pubValue = 0.0; // 定義
// B.cpp 直接用 A::GetPubValue() 或 A::pubValue
class DataCenter {
public:
static DataCenter& Instance() {
static DataCenter inst;
return inst;
}
double tempValue;
private:
DataCenter() = default;
};
// 任意處使用
DataCenter::Instance().tempValue = 3.14;
// 定義介面
class IDataListener {
public:
virtual void OnDataChanged(double newVal) = 0;
};
// A 管理監聽者
class A {
std::vector listeners;
public:
void AddListener(IDataListener* l) { listeners.push_back(l); }
void SetTempValue(double v) {
tempValue = v;
for (auto l : listeners) l->OnDataChanged(v);
}
};
// B 實作介面並註冊
class B : public IDataListener {
public:
void OnDataChanged(double v) override { /* 反應 */ }
};
| 場景 | 推薦做法 | 避免做法 |
|---|---|---|
| 單一全域資料 | 封裝類別 + 靜態存取函數 | 裸露 extern 全域變數 |
| 類別成員資料 | 持有物件指標/引用 | 複製資料導致不一致 |
| 多模組共享狀態 | 單例/依賴注入/事件總線 | 隨意包含頭檔造成循環依賴 |
現代 C++ 建議:優先使用依賴注入,透過建構函式傳遞介面指標,配合智慧指標管理生命週期,實現低耦合、高可測試性。