不能依赖合成的默认构造函数
- 【1】编译器只有在没有发现任何构造函数的情况下才会合成默认构造函数,一旦我们定义了其他的构造函数,那么除非再定义一个默认构造函数,否则类将没有默认构造函数。
-【2】 块中的内置类型或复合类型(数组,指针)如果默认初始化,则值会为未定义,将导致错误。除非类内的这些成员全部被赋予了类内初始值。 - 【 3】有时,编译器不能为某些类合成默认的构造函数。 如果类内包含一个其他类类型的成员,而且该成员的类型没有默认构造函数,则无法初始化。此时我们必须自定义构造函数,否则将没有可用的默认构造函数。
对于第2点,未定义有疑惑,故查资料
定义没有初始化式的变量时,系统有时候会帮我们初始化变量。系统如何初始化取决于变量的类型以及变量定义的位置。
内置类型变量是否自动初始化取决于变量定义的位置。函数体外定义的变量初始成0;函数体内定义的变量不进行自动初始化。除了用作赋值操作的左操作数,其他任何使用未初始化变量的行为都是未定义的,不要依赖未定义行为。
int类型
#include <iostream>
using namespace std;
int a;
int main()
{
int b;
cout << a << endl;
cout << b << endl;
return 0;
}
在VS执行这段代码,输出变量a的值0,同时VS会报错:Run-Time Check Failure #3 — The variable ‘b’ is being used without being initialized。 变量a被自动初始化为0;变量b未被自动初始化。
类成员变量
#include <iostream>
using namespace std;
class testA
{
public:
void printf() const
{
cout << data << endl;
}
private:
int data;
};
testA a;
int main()
{
testA b;
a.printf();
b.printf();
return 0;
}
类类型变量在定义时,如果没有提供初始化式,则会自动调用默认构造函数进行初始化(不论变量在哪里定义)。如果某类型没有默认构造函数,则定义该类型对象时必须提供显示初始化式。
定义数组时,如果没有显示提供初始化列表,则数组元素的自动化初始规则同普通变量一样:函数体外定义的内置类型数组,其元素初始为0;函数体内定义的内置类型数组,其元素无初始化;类类型数组无论在哪里定义,皆调用默认构造函数进行初始化,无默认构造函数则必须提供显示初始化列表。
如果定义数组时,仅提供了部分元素的初始列表,其剩下的数组元素,若是类类型则调用默认构造函数进行初始,若是内置类型则初始为0(不论数组定义位置)。
对于动态分配的数组,如果数组元素是内置类型,其元素无初始化;如果数组元素是类类型,依然调用默认构造函数进行初始化**。也可以在使用跟在数组长度后面的一对空圆括号对数组元素做值初始化**。
例如: int *ptrA = new int[10];
int *ptrB = new int[10] ();
其中ptrA指向的动态数组其元素未初始化,而ptrB指向的动态数组元素被初始化为0。
对于动态分配的单个对象,可使用直接初始化的语法规则在定义时显示初始化。如果不提供显示初始化式,动态创建的对象与在函数内部定义的变量初始化方式相同(即:内置类型无初始化,类类型调用默认构造函数进行初始化)。
来源:
【1】https://www.cnblogs.com/FoxShark/p/5802239.html