为什么C ++需要用户提供的默认构造函数来默认构造一个const对象? [英] Why does C++ require a user-provided default constructor to default-construct a const object?

查看:134
本文介绍了为什么C ++需要用户提供的默认构造函数来默认构造一个const对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++标准(第8.5节)说:

The C++ standard (section 8.5) says:


如果程序调用const限定对象的默认初始化类型T,T应为具有用户提供的默认构造函数的类类型。

If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type with a user-provided default constructor.

为什么?我不能想到在这种情况下需要用户提供的构造函数的任何原因。

Why? I can't think of any reason why a user-provided constructor is required in this case.

struct B{
  B():x(42){}
  int doSomeStuff() const{return x;}
  int x;
};

struct A{
  A(){}//other than "because the standard says so", why is this line required?

  B b;//not required for this example, just to illustrate
      //how this situation isn't totally useless
};

int main(){
  const A a;
}


推荐答案

类没有用户定义的构造函数,那么它可以是POD,并且默认情况下不会初始化POD类。所以如果你声明一个const对象的POD是未初始化的,它的用途是什么?所以我认为标准强制这个规则,以使对象实际上是有用的。

The reason is that if the class doesn't have a user-defined constructor, then it can be POD, and the POD class is not initialized by default. So if you declare a const object of POD which is uninitialized, what use of it? So I think the Standard enforces this rule so that the object can actually be useful.

struct POD
{
  int i;
};

POD p1; //uninitialized - but don't worry we can assign some value later on!
p1.i = 10; //assign some value later on!

POD p2 = POD(); //initialized

const POD p3 = POD(); //initialized 

const POD p4; //uninitialized  - error - as we cannot change it later on!

但是如果你使类为非POD:

But if you make the class a non-POD:

struct nonPOD_A
{
    nonPOD_A() {} //this makes non-POD
};

nonPOD_A a1; //initialized 
const nonPOD_A a2; //initialized 

注意POD和非POD之间的区别。

Note the difference between POD and non-POD.

用户定义的构造函数是使类为非POD的一种方法。有几种方法可以做到这一点。

User-defined constructor is one way to make the class non-POD. There are several ways you can do that.

struct nonPOD_B
{
    virtual void f() {} //virtual function make it non-POD
};

nonPOD_B b1; //initialized 
const nonPOD_B b2; //initialized 

注意nonPOD_B没有定义用户定义的构造函数。编译它。它将编译:

Notice nonPOD_B doesn't defined user-defined constructor. Compile it. It will compile:

  • http://www.ideone.com/h7TsA

并注释虚拟函数,然后按预期发生错误:

And comment the virtual function, then it gives error, as expected:

  • http://www.ideone.com/SWk7B

好吧,我想你误解了这段话。它首先说这个(§8.5/ 9):

Well, I think, you misunderstood the passage. It first says this (§8.5/9):


如果没有为一个对象指定初始值设定项,限定的)非POD类类型(或其数组),对象将被默认初始化; [...]

If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array thereof), the object shall be default-initialized; [...]

它涉及非POD类可能cv限定类型。也就是说,如果没有指定初始化程序,则非POD对象将被默认初始化。什么是默认初始化?对于非POD,规范说(§8.5/ 5),

It talks about non-POD class possibly cv-qualified type. That is, the non-POD object shall be default-initialized if there is no initializer specified. And what is default-initialized? For non-POD, the spec says (§8.5/5),


默认初始化类型T的对象意味着:

- 如果T是非POD类类型(子句9),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化不成功);

To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

它只是谈到T的默认构造函数,无论是用户定义的还是编译器生成的都是不相关的。

It simply talks about default constructor of T, whether its user-defined or compiler-generated is irrelevant.

如果你清楚了解这一点,那么请明白规范接下来说的是什么((8.5 / 9),

If you're clear up to this, then understand what the spec next says ((§8.5/9),


[...];如果对象是const限定类型,底层类类型应该有一个用户声明的默认构造函数。

[...]; if the object is of const-qualified type, the underlying class type shall have a user-declared default constructor.

因此,这段文字暗示,程序将是不成形的如果对象是 const限定 POD类型,并且没有初始化(因为POD不是默认初始化的):

So this text implies, the program will be ill-formed if the object is of const-qualified POD type, and there is no initializer specified (because POD are not default initialized):

POD p1; //uninitialized - can be useful - hence allowed
const POD p2; //uninitialized - never useful  - hence not allowed - error

顺便说一下,此编译精细,因为它的非POD,并且可以默认初始化

By the way, this compiles fine, because its non-POD, and can be default-initialized.

这篇关于为什么C ++需要用户提供的默认构造函数来默认构造一个const对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆