1. 類型別名作為成員(P243
除了定義數(shù)據(jù)和函數(shù)成員之外斋泄,類還可以自定義某種類型在類中的別名镐牺。
由類定義的類型名字和其他成員一樣存在訪問限制,
可以是public或者private中的一種募胃。
class A
{
public:
typedef std::string::size_type type_s;
private:
type_s a = 0;
};
我們在A
的public部分定義了type_s
,
這樣用戶就可以使用這個名字了A::type_s
摔认。
2. 類型的static成員(P269
我們通過在成員的聲明之前加上關(guān)鍵字static,使之與類關(guān)聯(lián)在一起电谣。
和其他成員一樣,靜態(tài)成員可以是public的或private的抹蚀。
類的靜態(tài)成員存在于任何對象之外,對象中不包含任何與靜態(tài)數(shù)據(jù)成員有關(guān)的數(shù)據(jù)晒来。
類似的郑现,靜態(tài)成員函數(shù)也不與任何對象綁定在一起,它們不包含this指針攒读。
class A
{
public:
const static int a = 0;
};
int main()
{
int b = A::a;
return 0;
}
3. 模板類型參數(shù)的類型成員(P593
以上我們用作用域運算符::
,來訪問類型成員和static成員薄扁。
在普通代碼中废累,編譯器掌握類的定義,
因此邑滨,它知道通過作用域運算符訪問的名字是類型還是static成員。
例如殿遂,string::size_type
是一個類型乙各,因為編譯器知道string
的定義。
但對于模板代碼就存在困難耳峦,例如假定T
是一個模板類型參數(shù),
當編譯器遇到類似T::a
這樣的代碼時驶乾,
它不會知道a
是一個類型成員還是一個static數(shù)據(jù)成員,直到實例化時才會知道级乐。
但是為了處理模板,編譯器必須知道名字是否表示一個類型风科。
例如,T::size_type * p
题山,編譯器需要知道故痊,
我們是正在定義一個名為p
的變量,
還是將一個名為size_type
的static數(shù)據(jù)成員與名為p
的變量相乘愕秫。
默認情況下,C++語言假定通過作用域運算符訪問的名字不是類型戴甩,
因此,如果我們希望使用一個模板類型參數(shù)的類型成員,
就必須顯式告訴編譯器該名字是一個類型备蚓。
我們通過使用關(guān)鍵字typename
來實現(xiàn)這一點。
template <typename T>
typename T::value_type top(const T &c) // 返回一個T::value_type類型
{
if (!c.empty())
{
return c.back();
}
return typename T::value_type(); // 調(diào)用T::value_type類型的構(gòu)造函數(shù)
}