命名空間
變體
動作

類別

出自 cppreference.com
< cpp‎ | language
 
 
C++ 語言
一般主題
流程控制
條件執行陳述式
if
疊代陳述式 (迴圈)
for
範圍 for (C++11)
跳躍陳述式
函式
函式宣告
Lambda 函式運算式
inline 指定符
動態例外規範 (直到 C++17*)
noexcept 指定符 (C++11)
例外
命名空間
型別
指定符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
儲存期指定符
初始化
 
 

類別是使用者定義的類型。

類別類型由 class-specifier 定義,它出現在 宣告 語法的 decl-specifier-seq 中。有關 class-specifier 的語法,請參閱 類別宣告

類別可以擁有多種類型的成員

1) 資料成員
2) 成員函式
3) 巢狀類型
a) 在類別定義內定義的 巢狀類別列舉
b) 使用 typedef 類型別名 (type alias) (C++11 起)宣告定義的現有類型別名
c) 類別在其自身定義內的名稱,為 查找 之目的,作為其自身的公用成員類型別名 (除非用於命名 建構函式):這被稱為 注入類別名稱 (injected-class-name)
4) 來自所有在類別內定義的非作用域 列舉列舉器,或由 using 宣告 (using-declarations)using-enum 宣告 (using-enum-declarations) 引入的(C++20 起)
5) 成員模板 (變數模板、(C++14 起)類別模板或函式模板) 可以出現在任何非局部類別/結構/聯合體的主體中。

所有成員都在類別定義中一次性定義,它們不能被新增到已定義的類別中 (不同於命名空間的成員)。

類別 T 的成員不能使用 T 作為其名稱,如果該成員是

  • 靜態資料成員、
  • 成員函式、
  • 成員類型、
  • 成員模板、
  • 列舉的列舉器 (除非該列舉是作用域列舉)(C++11 起),或
  • 成員匿名聯合體的成員。

然而,非靜態資料成員可以使用名稱 T,只要沒有使用者宣告的建構函式。

類別若至少有一個宣告或繼承的 虛擬 (virtual) 成員函式,則為多型 (polymorphic)。這種型別的物件是 多型物件 (polymorphic objects),並將執行期型別資訊儲存為物件表示的一部分,可透過 dynamic_casttypeid 進行查詢。虛擬成員函式參與動態繫結。

類別若至少有一個宣告或繼承的純虛擬成員函式,則為 抽象類別 (abstract class)。這種型別的物件無法被建立。

具有 constexpr 建構函式的類別是一個 字面量類型 (LiteralType):這種型別的物件可以在編譯時期由 constexpr 函式操作。

(C++11 起)

目錄

[編輯] 類別的屬性

可平凡複製的類別

可平凡複製的類別是指滿足以下條件的類別:

平凡類別

平凡類別是指滿足以下條件的類別:

(在 C++26 中棄用)

標準佈局類別

標準佈局類別是指滿足以下條件的類別:

  • 沒有類型為非標準佈局類別 (或此類型的陣列) 或參照的 非靜態資料成員
  • 沒有 虛擬函式,也沒有 虛擬基底類別
  • 對所有非靜態資料成員具有相同的 存取控制
  • 沒有非標準佈局基底類別,
  • 階層中只有一個類別具有非靜態資料成員,並且
  • 非正式地說,沒有任何基底類別與第一個非靜態資料成員具有相同的類型。或者,正式地說:假設類別為 S,則沒有任何類型集合 M(S) 中的元素作為基底類別,其中 M(X) 對於類型 X 定義為
  • 如果 X 是一個非聯合體類別類型,且沒有 (可能繼承的) 非靜態資料成員,則集合 M(X) 為空。
  • 如果 X 是一個非聯合體類別類型,其第一個非靜態資料成員的類型為 X0 (其中該成員可能是一個匿名聯合體),則集合 M(X) 包含 X0 以及 M(X0) 的元素。
  • 如果 X 是一個聯合體類型,則集合 M(X) 是所有 M(Ui) 的聯集以及包含所有 Ui 的集合,其中每個 Ui 是 X 的第 i 個非靜態資料成員的類型。
  • 如果 X 是一個元素類型為 Xe 的陣列類型,則集合 M(X) 包含 Xe 以及 M(Xe) 的元素。
  • 如果 X 是一個非類別、非陣列類型,則集合 M(X) 為空。

標準佈局結構體 (standard-layout struct) 是使用關鍵字 struct 或關鍵字 class 定義的標準佈局類別。標準佈局聯合體 (standard-layout union) 是使用關鍵字 union 定義的標準佈局類別。

(C++11 起)

[編輯] 隱式生命週期類別

隱式生命週期類別是指滿足以下條件的類別:

備註:隱式生命週期屬性已由缺陷報告 P0593R6 澄清。

[編輯] POD 類別

POD 類別是指滿足以下條件的類別:

  • 是一個 聚合體 (aggregate)
  • 沒有使用者宣告的複製賦值運算子,
  • 沒有使用者宣告的解構函式,並且
  • 沒有類型為非 POD 類別 (或此類型的陣列) 或參照的非靜態資料成員。
(直到 C++11)
  • 是一個平凡類別,
  • 是一個標準佈局類別,並且
  • 沒有類型為非 POD 類別 (或此類型的陣列) 的非靜態資料成員。
(C++11 起)

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 隱式生命週期類別可以具有使用者提供的解構函式 禁止
English Deutsch 日本語 中文(简体) 中文(繁體)