一. 回顾类内初始化成员变量
1、描述
在C++11
里,我们可以为类内成员变量提供一个初始值,那么我们在创建对象的时候,这个初始化值就用来初始化该成员变量。
普通成员变量不给初值的话,系统会默认给其一个缺省值(一个不确定的值),静态成员变量不给初值的话,系统会默认赋予零值。
2、类内成员变量初始化的方式
1)头文件内定义成员变量的时候直接赋予初值
class Time { Q_OBJECT public: Time(); int m_num = 10; //方式1 int m_num = {10}; //方式2
2)构造函数初始化列表(推荐,显得更专业)
参考:[C++ 从入门到精通] 8.构造函数详解、explicit、初始化列表
注意:
const
常量成员变量的初始化方式不可以在定义完常量成员变量之后,在构造函数里面进行初始化:
class Time { Q_OBJECT public: explicit Time(); //默认构造函数 //const int m_num = 10; //可以 const int m_num;
Time::Time() { Minute = 10; //不可以,报错表达式必须是可修改的左值 }
Time::Time():Minute(10) //构造函数初始化列表方式,可以 { }
二. 默认构造函数
1、定义:没有参数的构造函数,我们称为默认构造函数。
2、如何初始化类对象?
在生成类的对象时,会自动调用类的构造函数(构造函数初始化列表)来初始化成员变量。
class Time { public: Time() {}; int Hour; int Minute; }; Time::Time() :Hour(12), Minute(50) { }
int main() { Time myTime; //生成的对象没有参数,所以会调用默认构造函数 return 0; }
3、如果没有构造函数,如何初始化类对象?
class Time { public: //Time() {}; int Hour; int Minute; };
int main() { Time myTime; return 0; }
我们看到,即使屏蔽了函数所有的构造函数,在生成对象时,成员变量依然被系统赋予了一个默认的初始值。原因是在我们类定义时,如果没有构造函数的情况下,编译器就会为我们隐式的自动定义一个默认构造函数(无参),称为“合成的默认构造函数”。
4、合成的默认构造函数的作用:在没有构造函数的情况下,如果在定义成员变量的时候没有对其进行初始化,系统会在合成的默认构造函数中为其赋予一个默认初始值。如果在定义成员变量的时候对其进行了初始化,则在生成类对象时,其成员变量的初始值不变。
5、总结:
1)没有参数的构造函数,我们称为默认构造函数。在生成无参数的类对象时,会自动调用默认构造函数。
2)一般我们在定义类的时候都需要自定义一个构造函数对成员变量进行初始化的,这是比较正规的写法,合成的默认构造函数这个概念我们了解一下就好。
三. =default;和=delete;
1、=default;
=default;
为C++11
标准中引入的概念,编译器能够为=default;
的函数自动生成函数体,相当于定义了一个默认构造函数(不带参数):
class Time { public: //Time() {}; Time() = default; //适合默认构造函数,效果和上面等价 Time(int) = default; //不可以,报错“Time::Time(int)”: 不是可默认为的特殊成员函数 };
注:只有特殊函数(默认构造函数、析构函数、拷贝构造函数等)才可以使用= default;
。非特殊函数(带参数的构造函数、普通成员函数)不可以使用= default;
。= default;
等价于{}
。
2、=delete;
=delete;
:显示的禁用某个函数。
class Time { public: Time() = delete; //禁止系统生成合成的默认的构造函数 };
这时,我们在生成类对象时:
int main() { Time myTime; //失败,由于没有默认构造函数,系统也无法自动生成合成的默认构造函数 return 0; }
下雨天,最惬意的事莫过于躺在床上静静听雨,雨中入眠,连梦里也长出青苔。 |