類別
類別是使用者定義的類型。
類別類型由 class-specifier 定義,它出現在 宣告 語法的 decl-specifier-seq 中。有關 class-specifier 的語法,請參閱 類別宣告。
類別可以擁有多種類型的成員
所有成員都在類別定義中一次性定義,它們不能被新增到已定義的類別中 (不同於命名空間的成員)。
類別 T 的成員不能使用 T 作為其名稱,如果該成員是
- 靜態資料成員、
- 成員函式、
- 成員類型、
- 成員模板、
- 列舉的列舉器 (除非該列舉是作用域列舉)(C++11 起),或
- 成員匿名聯合體的成員。
然而,非靜態資料成員可以使用名稱 T,只要沒有使用者宣告的建構函式。
類別若至少有一個宣告或繼承的 虛擬 (virtual) 成員函式,則為多型 (polymorphic)。這種型別的物件是 多型物件 (polymorphic objects),並將執行期型別資訊儲存為物件表示的一部分,可透過 dynamic_cast 和 typeid 進行查詢。虛擬成員函式參與動態繫結。
類別若至少有一個宣告或繼承的純虛擬成員函式,則為 抽象類別 (abstract class)。這種型別的物件無法被建立。
|
具有 constexpr 建構函式的類別是一個 字面量類型 (LiteralType):這種型別的物件可以在編譯時期由 constexpr 函式操作。 |
(C++11 起) |
目錄 |
[編輯] 類別的屬性
可平凡複製的類別可平凡複製的類別是指滿足以下條件的類別:
標準佈局類別標準佈局類別是指滿足以下條件的類別:
標準佈局結構體 (standard-layout struct) 是使用關鍵字 struct 或關鍵字 class 定義的標準佈局類別。標準佈局聯合體 (standard-layout union) 是使用關鍵字 union 定義的標準佈局類別。 |
(C++11 起) |
[編輯] 隱式生命週期類別
隱式生命週期類別是指滿足以下條件的類別:
- 是一個 聚合體 (aggregate),且其解構函式不是 使用者宣告的(C++11 前)使用者提供 (user-provided) 的(C++11 起),或
- 至少有一個平凡的合格建構函式,以及一個平凡的、非刪除的解構函式。
備註:隱式生命週期屬性已由缺陷報告 P0593R6 澄清。
[編輯] POD 類別POD 類別是指滿足以下條件的類別:
POD 結構體 (POD struct) 是一個非聯合體的 POD 類別。POD 聯合體 (POD union) 是一個屬於 POD 類別的聯合體。 |
(C++20 中已棄用) |
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯應用於之前的 C++ 標準。
| DR | 應用於 | 出版時的行為 | 正確的行為 |
|---|---|---|---|
| CWG 148 | C++98 | POD 類別不能包含指向成員的指標, 這些指標本身就是 POD (純量) 類型 |
限制已移除 |
| CWG 383 | C++98 | 複製賦值運算子或解構函式可以 在 POD 類別中被使用者宣告,如果它們未被定義 |
不允許 |
| CWG 1363 | C++11 | 一個同時具有平凡預設建構函式和非平凡 預設建構函式的類別可以是平凡的 |
它是非平凡的 |
| CWG 1496 | C++11 | 一個只具有以下建構函式的類別 都被定義為已刪除,但可以是平凡的 |
它是非平凡的 |
| CWG 1672 | C++11 | 一個類別可以是標準佈局類別 如果它有多個空的基底類別 |
它不是一個標準佈局類別 |
| CWG 1734 | C++11 | 可平凡複製的類別不能具有非平凡的 已刪除的複製/移動建構函式/賦值運算子 |
如果已刪除,可以是平凡的 |
| CWG 1813 | C++11 | 如果一個類別具有 繼承了非靜態資料成員的基底類別,則它從來不是標準佈局類別 |
它可以是標準佈局類別 |
| CWG 1881 | C++11 | 對於標準佈局類別及其基底類別, 未命名的位元欄位可能在 宣告資料成員的不同類別中宣告 |
所有非靜態資料成員 和位元欄位需要首先 在同一個類別中宣告 |
| CWG 1909 | C++98 | 成員模板可以與其類別同名 | 禁止 |
| CWG 2120 | C++11 | 在判斷標準佈局類別時,M(X) 的定義 沒有考慮 第一個成員是陣列的類別 |
已在 M(X) 的定義中處理此情況 |
| CWG 2605 | C++98 | 隱式生命週期類別可以具有使用者提供的解構函式 | 禁止 |