为什么我需要一个构造函数?

fun*_*uns 10 c++ oop constructor

#include<iostream>
using namespace std;

class A {
public:
    int i;
};

int main() {
  const A aa;  //This is wrong, I can't compile it! The implicitly-defined constructor does not initialize ‘int A::i’
}
Run Code Online (Sandbox Code Playgroud)

我用的时候

class A {
public:
  A() {}
  int i;
};
Run Code Online (Sandbox Code Playgroud)

还行吧!我可以编译它!为什么我使用隐式定义的构造函数时无法编译它?

Mik*_*our 10

为什么隐式定义的构造函数不起作用?

它确实有效,但其中一个语言规则是它不能用于初始化一个const对象,除非它初始化所有成员; 并且它不会像普通类型那样初始化成员int.这通常是有道理的,因为以后const没有办法给他们一个价值.

(这是一个小小的简化;请参阅语言标准的章节和经文的评论.)

如果你定义了自己的构造函数,那么你就是说你知道自己在做什么,并且不希望初始化该成员.编译器将允许您甚至为const对象使用它.

如果要将其设置为零,则可以初始化对象:

const A aa {};    // C++11 or later
const A aa = A(); // historic C++
Run Code Online (Sandbox Code Playgroud)

如果要将其设置为其他值,或者将其设置为零而用户不必指定value-initialisation,那么您将需要一个初始化成员的构造函数:

A() : i(whatever) {}
Run Code Online (Sandbox Code Playgroud)


Jon*_*ely 9

为什么隐式定义的构造函数不起作用?

因为C++标准如此说:

[dcl.init]第7段: 如果程序要求对const限定类型的对象进行默认初始化T,T则应为具有用户提供的默认构造函数的类类型.

这可确保您不会创建const包含以后无法初始化的未初始化数据的对象.

要初始化const限定对象,您需要拥有用户提供的默认构造函数或使用初始化器:

const A aa = A();
Run Code Online (Sandbox Code Playgroud)

这里aa使用表达式A()初始化对象,该表达式是一个值初始化对象.您可以在没有默认构造函数的情况下对类类型进行值初始化,因为如果类型没有默认构造函数,则value-initialization将值设置为零.

但是,标准中的规则过于严格,因为它禁止使用隐式定义的构造函数,即使没有数据成员或所有数据成员都有合理的默认构造函数,因此有一个缺陷报告反对标准建议更改它,请参阅问题253.


Sad*_*que 0

因为i没有初始化。

class A 
{ 
    public:
    A()
    {
        i =0;
    }
    int i;
};
Run Code Online (Sandbox Code Playgroud)

“隐式构造函数”是指自动为您生成的构造函数,并会生成错误,因为它意识到无法初始化 的值i。这可以是无参数构造函数、复制构造函数或(从 C++11 开始)移动构造函数。