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[std::string] {
int get(std::string s) const { ... }
void set(int v, std::string s) { ... }
}
// ...
};
int main() {
Demo2 d;
std::string s("CLI");
d.x[s] = 3; // Calls Demo2::x::set(3, s)
return d.x[s]; // Calls Demo2::x::get(s)
}
注意,指定索引的屬性不能是靜態變量。
多維的索引屬性也是可以的,它引入的操作語法與C/C++中數組元素操作方法不太一樣,例如:
struct Demo3 {
property double x[std::string, int] {
double get(std::string s, int n) const { ... }
void set(double v, std::string s, int n) { ... }
}
// ...
};
int main() {
Demo3 d;
std::string s("CLI");
d.x[s, 7] = 42.0; // Calls Demo3::x::set(42.0, s, 7)
return d.x[s, 7] != 42.0; // Calls Demo3::x::get(s, 7)
}
後面的這一個例子說明了出現在括號內的操作索引屬性的逗號符號是表達式操作符號,而不是一個逗號操作符。(下面將討論這種規則帶來的後果)。
(四)默認的索引屬性
除了對象被編入偽域外,默認的索引屬性與指定的索引屬性非常相象,對象本身可以索引(仿佛它自身有一個[]操作成員函數一樣),以前的代碼只要稍微改動一下就可以說明這種變化。
struct Demo4 {
property double default[std::string, int] {
double get(std::string s, int n) const { ... }
void set(double v, std::string s, int n) { ... }
}
// ...
};
int main() {
Demo4 d;
std::string s("CLI");
d[s, 7] = 42.0; // Calls Demo4::default::set(42.0, s, 7)
return d[s, 7] != 42.0; // Calls Demo4::default::get(s, 7)
}
請關注關鍵詞"default"代替屬性名的用法。
四、一些技術性問題
歐洲計算機制造商協會(C++/CLI標准的制訂者)已經研究並解決了引入屬性所帶來的若干問題,下面這些內容尤其值得關注。
(一)多維索引屬性的操作
p->x[2, 3]表達式擁有不同的意思,這要視成員x是否是屬性(這種情況下逗號分隔兩個索引屬性)或其它成員變量(這種情況下逗號是個操作符號,表達式的意思等同於p->x[3])而定。為了在一個屬性索引中獲取逗號操作符的效果,開發人員可以使用圓括號(即p->x[(2, 3)])。
(注意,在依賴模版的表達式中,這將產生模糊性,並且直到實例化時問題才能得到解決)
(二)屬性名與類型名沖突
微軟.NET框架帶有很多包含屬性的類(這些類最初並不是使用C++/CLI來開發的),這些包含的屬性名與屬性類型的名字相同,例如:
typedef int Color;
struct Conflict {
property Color Color { // Property name hides type name
typename Color get() const;
void set(typename Color);
}
// ...
};
}
為了幫助在這種上下文中書寫代碼,C++/CLI計劃添加語法,使用關鍵詞typename來標識不標准的類型(特別是"屬性"),查找標志符的過程中將被忽視。上述的代碼就以這種新的形式使用typename關鍵詞。
(三)重載的索引屬性
索引屬性可以被重載,即,幾個指定索引屬性可以使用同一個名字共存於同一個類中,假定它們可以根據屬性的類型來區分開來。相似地,默認的索引屬性可以使用其他屬性或操作符[]來重載。解決兩意性與重載行為的規則已經被建立起來,來處理上述情況。
(四)保留的成員名字
C++/CLI屬性通過綜合特定的成員來實現,這些成員的名義由微軟的.NET框架來規定,並且必須得到保留。
如果一個類包含分層的屬性或指定索引屬性X,成員名 get_X 和set_X在類中得到保留(即使屬性僅僅包含一個操作函數也是這樣)。相似地,如果一個類包含有一個默認的索引屬性,類中的成員函數get_Item 和set_Item也將得到保留。