首页 >后端开发 >C++ >为什么 C 中的私有默认构造函数在与大括号一起使用时可以工作,但与括号一起使用时会失败?

为什么 C 中的私有默认构造函数在与大括号一起使用时可以工作,但与括号一起使用时会失败?

Susan Sarandon
Susan Sarandon原创
2024-11-11 14:00:03456浏览

Why does a private default constructor in C   work when used with curly braces but fail with parentheses?

默认构造函数的私有影子

当声明一个类型并打算使其默认构造函数私有时,使用 default 关键字可能无法实现期望的结果,如下面的代码所示片段:

class C {
    C() = default;
};

int main() {
    C c;           // error: C::C() is private within this context (g++)
                   // error: calling a private constructor of class 'C' (clang++)
                   // error C2248: 'C::C' cannot access private member declared in class 'C' (MSVC)
    auto c2 = C(); // error: as above
}

令人惊讶的是,尽管显式将构造函数设为私有,但此代码仍会生成错误。但是,以下代码可以成功编译:

class C {
    C() = default;
};

int main() {
    C c{};         // OK on all compilers
    auto c2 = C{}; // OK on all compilers
} 

为什么构造函数在与大括号一起使用时表现不同?

C 14 默认构造函数默认性

关键在于C 14标准(8.4.2/5 [dcl.fct.def.default]),它将“用户提供的”函数定义为“用户声明的函数,并且在第一次声明时未显式默认或删除”。这意味着我们示例中的默认构造函数不被视为用户提供的,因为它是显式默认的。

聚合构造函数照明

因此,类 C 具有没有用户提供的构造函数。因此,根据 8.5.1/1 [dcl.init.aggr],它被分类为聚合,其中指出聚合是“没有用户提供的构造函数、没有私有或受保护的非静态的数组或类”数据成员,没有基类,也没有虚函数。”

聚合构造大括号

聚合有一个特殊的构造规则,允许使用大括号 {} 来构造它们,即使它们具有私有构造函数。此规则旨在简化通常包含多个成员的聚合(例如数组和结构体)的初始化。

因此,类 C 的构造函数虽然标记为私有,但仍然可以在大括号内使用,因为类本身被认为是一个聚合。

以上是为什么 C 中的私有默认构造函数在与大括号一起使用时可以工作,但与括号一起使用时会失败?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn