C++中默认无参构造函数的工作机制浅析
北冥有鱼丶丶 人气:0在不实现构造函数的情况下,编译器会自动生成一个默认无参构造函数。但是看起来编译器自动生成的无参默认构造函数似乎没有什么用,比如创建p对象时调用了编译器生成的无参默认构造函数,但是p对象的成员变量依旧是随机值。
class Person { private: int age; public: int getAge() { return age; } }; int main() { Person p; cout << p.getAge() << endl; return 0; }
默认无参构造函数真的没有用吗?
我们可以通过下面的代码来探究默认无参构造函数的作用。
#include<iostream> #include<string> using namespace std; class Person { int age; public: Person() { cout << "自定义类型成员的默认无参构造函数被调用" << endl; } //Person(int _age = 0) :age(_age) { cout << "自定义类型成员的全缺省默认构造函数被调用" << endl; } int getAge() { return age; } }; class Student { Person p; int id; public: Student(){} int getId() { return id; } int getAge() { return p.getAge(); } }; int main() { Student s; cout << "id:" << s.getId() << endl; cout << "age:" << s.getAge() << endl; return 0; }
上面代码利用默认无参构造函数创建对象s,根据第一句输出,我们可以得知默认无参构造函数会先对自定义类型的数据成员会调用自定义数据类型的默认构造函数来处理自定义类型数据成员。根据第二句输出,我们可以知道默认无参构造函数对基本类型数据成员没有作处理,只是在初始化列表中用随机值对其进行了初始化,第三句输出,是默认无参构造函数调用了自定义类型的默认构造函数对自定义数据成员处理的结果,由于自定义类型的默认构造函数也是默认无参构造函数,所以它不会对基本数据类型成员age作处理,只是在初始化列表中用随机值对其进行初始化。
我们把第八行代码屏蔽,放出第九行全缺省默认构造函数试试看,输出如下:
上面代码利用默认无参构造函数创建对象s,根据第一句输出,我们可以得知默认无参构造函数会先对自定义类型的数据成员会调用自定义数据类型的默认构造函数来处理自定义类型数据成员,与之前不同的是,之前自定义数据类型的默认构造函数是默认无参构造函数,这里自定义类型的默认构造函数,是自己定义的全缺省的默认构造函数。根据第二句输出,我们可以知道默认无参构造函数对基本类型数据成员没有作处理,只是在初始化列表中用随机值对其进行了初始化,第三句输出,是默认无参构造函数调用了自定义类型的全缺省默认构造函数对自定义数据成员处理的结果。
由此我们可以得出结论:
C++把类型分成基本类型和自定义类型。
默认无参默认构造函数对基本类型成员变量不做处理(在初始化列表中用随机值对其进行初始化),C++11 中针对基本类型成员不初始化的缺陷,又打了补丁,即:基本类型成员变量在类中声明时可以给默认值。
默认无参构造函数对于自定义类型成员变量才会处理,它会去调用自定义类型的默认构造函数去初始化创建自定义类型的成员变量(对象)。
何时使用编译器自动生成的无参默认构造函数就够了,何时需要自己实现构造函数呢?
如果一个类中的成员全是自定义类型,或者基本类型成员在声明时已经给了缺省值,即无需对基本类型成员变量做处理,且自定义成员都提供了默认构造函数,此时使用编译器自动生成的无参默认构造函数就可以了。
如果有基本类型的成员变量且需要显示传参初始化,即我们需要自己对基本类型成员变量进行处理,或者自定义类型成员没有默认构造函数,那么就要自己实现构造函数。
加载全部内容