一、构造函数的调用规则
-
构造函数的调用时机:
-
当创建类的对象时,构造函数会被自动调用。
- 使用
new
分配对象内存时 - 直接在栈上或全局/静态存储区创建对象。
- 使用
-
-
构造函数的特点:
- 构造函数的名字必须与类名完全相同。
- 构造函数没有返回类型,连
void
也不写。 - 构造函数可以有参数,也可以重载。
- 如果类中没有显式定义任何构造函数,编译器会提供一个默认的构造函数。
二、默认生成的函数
如果类内没有显式定义任何成员函数(包括构造函数、析构函数、拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符),编译器会根据需要默认生成以下函数(称为特殊成员函数):
-
默认构造函数:
- 如果类中没有定义任何构造函数,编译器会提供一个默认的无参构造函数。
- 如果类中定义了其他构造函数(无论是带参还是无参),编译器就不会再提供默认构造函数。
-
析构函数:
- 析构函数用于在对象生命周期结束时进行清理工作(如释放资源)。
- 如果类中没有定义析构函数,编译器会提供一个默认的析构函数。
-
拷贝构造函数:
- 用于创建一个对象的副本。
- 如果类中没有定义拷贝构造函数,编译器会提供一个默认的拷贝构造函数,该构造函数会进行成员级的浅拷贝。
-
拷贝赋值运算符:
- 用于将一个对象的值赋给另一个同类型的对象。
- 如果类中没有定义拷贝赋值运算符,编译器会提供一个默认的拷贝赋值运算符,该运算符也会进行成员级的浅拷贝。
-
移动构造函数(C++11及以后):
- 用于从另一个即将被销毁的对象那里“窃取”资源。
- 如果类中没有定义移动构造函数,且类的某个成员类型定义了移动构造函数,编译器可能会生成一个移动构造函数。但如果没有移动构造函数的需求,编译器不会默认生成。
-
移动赋值运算符(C++11及以后):
- 类似于移动构造函数,但用于赋值操作。
- 同样的,如果类中没有定义移动赋值运算符,且类的某个成员类型定义了移动赋值运算符,编译器可能会生成一个。但如果没有需求,编译器不会默认生成。