本文探討 ECMA 正在制定的 C++/CLI 標準中關於「屬性」的語言擴展。非標準 C++ 建議,亦非背書,旨在分析 C++/CLI 在此領域的發展方向。
C++/CLI 屬性類似受限制的資料成員,操作會轉化為存取函式呼叫 (get/set):
struct Demo1 {
property int Val {
int get() const {
++Demo1::access_count;
return this->value;
}
void set(int v) {
++Demo1::access_count;
this->value = v;
}
}
private:
int value;
static unsigned long access_count;
};
int main() {
Demo1 d;
d.Val = 3; // 呼叫 set
return d.Val; // 呼叫 get
}
get/set 至少須有一個,不可同時省略。&Demo1::Val::set)。virtual,支援純虛擬屬性。標準 C++ 慣用 get/set 函式封裝資料。在 .NET 執行環境中,屬性可透過中繼資料在執行期發現與修改,視覺化設計工具即利用此機制列出元件屬性並觸發 GUI 更新事件。
使用 static 關鍵字,存取函式為靜態,呼叫語法同靜態資料成員 (C::P)。
以分號替代函式主體,編譯器自動產生支援欄位與存取函式:
struct TrivialProp { property int Val; };
等同於:
struct TrivialProp {
property int Val {
int get() const { return this->__Val; }
void set(int v) { this->__Val = v; }
}
private: int __Val;
};
使用陣列語法操作集合:
struct Demo2 {
property int x[String^] {
int get(String^ s) const { ... }
void set(int v, String^ s) { ... }
}
};
// 使用
d.x["CLI"] = 3; // 呼叫 set(3, "CLI")
int v = d.x["CLI"]; // 呼叫 get("CLI")
支援多維索引:property double x[String^, int],呼叫語法 d.x[s, 7] = 42.0。注意逗號為索引分隔符,非運算子;需逗號運算子效果時用括號 d.x[(2, 3)]。
使用 default 關鍵字,物件本身可直接索引:
struct Demo4 {
property double default[String^, int] { ... }
};
// 使用
d["CLI", 7] = 42.0; // 呼叫 default::set(42.0, "CLI", 7)
p->x[2, 3] 中逗號意義取決於 x 是否為屬性。需逗號運算子時加括號。typename 關鍵字標識型別,避免被屬性名遮蓋。property Color Color { typename Color get(); void set(typename Color); }operator[] 多載。已建立消歧義規則。X 保留 get_X/set_X;預設索引屬性保留 get_Item/set_Item。