當C 中的「私有」建構子變成公用
在C 中,將類型的預設建構子宣告為私有會限制其可訪問性。但是,在某些情況下,此限制可能會被意外繞過。
考慮以下範例:
class C { C() = default; // Private default constructor }; int main() { C c; // Error: Constructor is private auto c2 = C(); // Error: Constructor is private }
在這種情況下,由於私有建構函數,兩次建立 C 實例的嘗試都會失敗。令人驚訝的是,當使用大括號直接初始化C 時,這個限制似乎被解除了:
class C { C() = default; }; int main() { C c{}; // Success: Curly braces allow object initialization auto c2 = C{}; // Success: Initialization not affected by private constructor }
揭示技巧
這種特殊的行為源自於C 14 的聚合初始化規則。根據 [dcl.fct.def.default] 的 8.4.2/5,如果預設建構子在其第一個聲明中明確默認,則不將其視為「使用者提供的」。由於 C 的預設建構函數符合此條件,因此不會將其視為使用者提供的。
因此,C 滿足[dcl.init.aggr] 8.5.1/1 中聚合的定義:它沒有使用者提供的建構子、私人或受保護的非靜態資料成員、基底類別或虛函數。
聚合初始化
聚合是一種具有簡化初始化的特殊型別規則。在這種情況下,大括號表示聚合初始化,即使使用私有建構函式也允許建立物件。在我們的例子中,編譯器將 {} 視為初始值設定項列表,繞過私有建構函式限制並將 C 初始化為聚合。
以上是為什麼使用大括號允許在 C 中使用私有預設建構函式初始化類別?的詳細內容。更多資訊請關注PHP中文網其他相關文章!