简体   繁体   English

class 类型的值初始化

[英]Value-initialization of class types

Percppreference , the syntax for value initialization is:根据cppreference ,值初始化的语法是:

  • [..] [..]
  • T object {}; (since C++11) (C++11 起)
  • [..] [..]

It's already known that value-initialization is performed when an object is constructed with an empty initializer.众所周知,当使用空初始化程序构造 object 时会执行值初始化。

Per, [dcl.init]/8 ( emphasis mine )每, [dcl.init]/8强调我的

To value-initialize an object of type T means:对 T 类型的 object 进行值初始化意味着:

  • (8.1) if T is a (possibly cv-qualified) class type ([class]), then (8.1) 如果 T 是(可能是 cv 限定的)class 类型([class]),那么
    • (8.1.1) if T has either no default constructor ([class.default.ctor]) or a default constructor that is user-provided or deleted , then the object is default-initialized; (8.1.1) 如果 T没有默认构造函数([class.default.ctor]) 或用户提供或删除默认构造函数,则 object 是默认初始化的;
    • (8.1.2) otherwise, the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized; (8.1.2) 否则,object 是零初始化的,并检查默认初始化的语义约束,如果 T 具有非平凡的默认构造函数,则 object 是默认初始化的;
  • (8.2) [..] (8.2) [..]
  • (8.3) [..] (8.3) [..]

I interpret the term "no default constructor" as that there's no default constructor declared in the class.我将术语“无默认构造函数”解释为在 class 中没有声明默认构造函数。 For example,例如,

class S
{
    long double d;
    friend void f(const S&);
};

void f(const S& s) { std::cout << s.d; }

int main()
{
    S s{ };
    f(s); // 0
}

Since the class has "no default constructor" , I'm expecting that the object s is default-initialized and the member sd has indeterminate value.由于 class 有“没有默认构造函数” ,我期待s是默认初始化的,并且成员sd具有不确定的值。 Why that's not the case?为什么不是这样?

I also have a confusion in understanding the point (8.1.1).我对这一点(8.1.1)的理解也很困惑。 How I can write this line of code T object {} without having a default constructor or with having a deleted default constructor?在没有默认构造函数或删除默认构造函数的情况下,如何编写这行代码T object {} Notice the bold part, It's said that, "if T has either no default constructor or a default constructor that is deleted.."注意粗体部分,据说, “如果 T 没有默认构造函数或默认构造函数被删除..”

Are there situations where objects of class types are value-initialized with deleted default constructor or without default constructor at all?是否存在 class 类型的对象使用已删除的默认构造函数或根本没有默认构造函数进行值初始化的情况? Am I misreading 8.1.1?我误读了 8.1.1 吗?

Your class S does have a default constructor;您的 class S确实有一个默认构造函数; it is just defined implicitly.它只是隐式定义的。

Per [class.default.ctor]/1 :每个[class.default.ctor]/1

A default constructor for a class X is a constructor of class X for which each parameter that is not a function parameter pack has a default argument (including the case of a constructor with no parameters). class X默认构造函数是 class X的构造函数,其中每个不是 function 参数包的参数都有一个默认参数(包括没有参数的构造函数的情况)。 If there is no user-declared constructor for class X , a non-explicit constructor having no parameters is implicitly declared as defaulted ([dcl.fct.def]).如果 class X没有用户声明的构造函数,则将不带参数的非显式构造函数隐式声明为默认构造函数 ([dcl.fct.def])。 An implicitly-declared default constructor is an inline public member of its class.隐式声明的默认构造函数是其 class 的内联公共成员。

Therefore S{} will zero-initialize the object per [dcl.init]/8.1.2.因此S{}将按照 [dcl.init]/8.1.2 对 object 进行零初始化。

When [dcl.init]/8.1.1 refers to classes with no default constructor it means classes where the implicit default constructor doesn't get generated because user-defined constructors exist.当 [dcl.init]/8.1.1 引用没有默认构造函数的类时,它意味着由于存在用户定义的构造函数而不会生成隐式默认构造函数的类。 That is, (8.1.1) would apply to the following classes:也就是说,(8.1.1) 将适用于以下类:

struct NoDefaultCtor
{
    NoDefaultCtor(int) {}
};

struct UserProvidedDefaultCtor
{
    UserProvidedDefaultCtor() {}
};

struct DeletedDefaultCtor
{
    DeletedDefaultCtor() = delete;
};

For all three of those classes, value-initialization will perform default-initialization.对于所有这三个类,值初始化将执行默认初始化。 In the case of NoDefaultCtor and DeletedDefaultCtor that default-initialization will fail, of course, but it's important that (8.1.1) catches those types so they don't fall through and get zero-initialized by (8.1.2).NoDefaultCtorDeletedDefaultCtor的情况下,默认初始化当然会失败,但重要的是 (8.1.1) 捕获这些类型,这样它们就不会失败并被 (8.1.2) 初始化为零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM