C++的各种初始化方式(3)

没有使用括号,就是默认初始化。可以简单理解成,你放任不管,允许编译器使用默认行为。通常这是糟糕的行为,除非你真的懂自己在干什么。

4. 列表初始化是C++新标准给出的一种初始化方式,可用于内置类型,也可以用于自定义对象,前者比如数组,后者比如vector。典型的:

int array[5]={1,2,3,4,5}; vector<int> v={1,2,3,4,5};

文章写到这里,读者认真的看到这里,似乎已经懂了C++的各种初始化规则和方式,下面用几个例子来检测一下:

#include <iostream> using namespace std; class Init1 { public: int i; }; class Init2 { public: Init2() = default; int i; }; class Init3 { public: Init3(); int i; }; Init3::Init3() = default; class Init4 { public: Init4(); int i; }; Init4::Init4() { //constructor } class Init5 { public: Init5(): i{} { } int i; }; int main(int argc, char const *argv[]) { Init1 ia1; Init1 ia2{}; cout << "Init1: " << " " << "i1.i: " << ia1.i << "\t" << "i2.i: " << ia2.i << "\n"; Init2 ib1; Init2 ib2{}; cout << "Init2: " << " " << "i1.i: " << ib1.i << "\t" << "i2.i: " << ib2.i << "\n"; Init3 ic1; Init3 ic2{}; cout << "Init3: " << " " << "i1.i: " << ic1.i << "\t" << "i2.i: " << ic2.i << "\n"; Init4 id1; Init4 id2{}; cout << "Init4: " << " " << "i1.i: " << id1.i << "\t" << "i2.i: " << id2.i << "\n"; Init5 ie1; Init5 ie2{}; cout << "Init5: " << " " << "i1.i: " << ie1.i << "\t" << "i2.i: " << ie2.i << "\n"; return 0; }

试问上面代码中,main程序中的各个输出值是多少?先不忙使用编译器编译程序,根据之前介绍的知识先推断一番:

首先,我们需要明白,对于类来说,构造函数是用来负责类对象的初始化的,一个类对象无论如何一定会被初始化。也就是说,当实例化类对象时,一定会调用构造函数,不论构造函数是否真的初始化了数据成员。故而对于没有定义任何构造函数的自定义类来说,该类的默认构造函数不存在“被需要/不被需要”这回事,它必然会被合成。

对于Init1,由于我们对其没有做任何构造函数的声明和定义,因此会合成默认构造函数。

对于Init2,我们在类内部声明处要求合成默认构造函数,因此也会有合成的默认构造函数。

由于Init1和Init2它们拥有类似的合成默认构造函数,因此它们的ia1.i和ib1.i值相同,应该都是随机值,而ia2.i和ib2.i被要求值初始化,因此它们的值都是0。

对于Init3,我们在类外部定义处要求编译器为我们生成默认构造函数,此默认构造函数为用户自定义的默认构造函数。

对于Init4,我们显式的定义了用户自定义默认构造函数。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/80815bb8a00ef25e77c25c7279903033.html