当 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中文网其他相关文章!