文章目录
- 构造函数
- 类型
- 参考博客
😊点此到文末惊喜↩︎
构造函数
类型
- 默认构造函数(缺省构造函数)
- 一个类中只能出现一个默认构造函数
- 在调用时,不需要传入实参。因为默认构造函数通常是无参的或所有形参都有缺省值
- 使用默认构造函数的时候创建对象不能后面带有括号
- 编译器自动生成non-trivial的构造函数有四种情况,其他情况就算编译器产生了默认构造函数也没有实质作用。
- 类中有类:类A含有类B的对象作为成员,并且类B显式定义了默认构造函数,则定义类A对象的时候编译器会产生一个默认构造函数,并在这个默认构造函数中提供了调用类B构造函数的代码。
- 类继承类:类B继承于类A,且类A显式定义了构造函数,那么在生成类B对象的过程中编译器同样会产生一个默认构造函数,在这个构造函数中提供调用基类A构造函数的代码
- 含虚函数类:某个类含有虚函数,那么编译器会自动产生一个默认构造函数以提供虚表指针相关的初始化操作
- 虚继承基类:一个类虚继承于其他类,那么同样的编译器会为该类产生默认的构造函数。
- 初始化构造函数(有参构造函数)
- 在创建对象时,使用实参为对象的成员属性赋值,由编译器自动调用
- 复制 / 拷贝构造函数
- 若没有显示定义复制构造函数,则系统会默认创建一个复制构造函数,当类中有指针成员时,由系统默认创建的复制构造函数会存在“浅拷贝”的风险,因此必须显示定义复制构造函数。
- 复制构造函数参数为类对象本身的引用,根据调用对象进行深拷贝构建实参对象
- 被调用的三种情况
- 对象用于给其他对象进行赋值初始化
- 对象作为函数形参
- 对象作为函数返回值,实质是返回值对象作为类复制构造函数实参而调用
// 1. 对象的赋值初始化 Complex c2(c1); Complex c2 = c1; // 2. 函数形参 void Function(Complex c){... }// 可以使用const & :确保实参的值不会改变,并避免复制构造函数带来的深拷贝开销 void Function(const Complex & c){} //3. 函数返回值 Complex Func() {Complex a(4);return a; }
- 移动构造函数
- 临时对象转移内存所属权时调用,使用右值引用作为参数。
class Integer {private:int* m_ptr;public:Integer(Integer&& source)// 注意形参是右值引用: m_ptr(source.m_ptr) {source.m_ptr= nullptr;cout << "Call Integer(Integer&& source)移动" << endl;}};int main(int argc, char const* argv[]) {Integer a;Integer b(std::move(a));// 将a转换成右值引用return 0;}
- 委托构造函数
- 构造函数可以在同一个类中一个构造函数调用另一个构造函数,从而达到简化代码的目的。
#include <iostream> class Base { public:int value1;int value2;Base() //目标构造函数{value1 = 1;}Base(int value) : Base() //委托构造函数{ // 委托 Base() 构造函数value2 = value;} }; void EntrustedConstruction() {Base b(2); //首先调用Base(int value) : Base() 毫无疑问//然后会走到base()中,先给value1复制,然后走到Base(int value) : Base() ,给value2赋值std::cout << b.value1 << std::endl;std::cout << b.value2 << std::endl; }
- 转换构造函数
- 只有一个参数的构造函数,而且该参数又不是本类的const引用
#include <iostream> using namespace std;class Student{ public://1. 默认构造函数,没有参数或形参具有缺省值Student(int i=2){this->age = 20;this->num = 1000;}; // 2. 初始化构造函数,有参数和参数列表Student(int a, int n):age(a), num(n){};// 3. 拷贝构造函数,参数是对象Student(const Student& s){this->age = s.age;this->num = s.num;};// 4. 移动构造函数,参数是右值引用Student(const Student&& s){this->age = s.age;this->num = s.num;}; // 3. 转换构造函数,形参是其他类型变量,且只有一个形参Student(int r){ //this->age = r;this->num = 1002;};~Student(){} public:int age;int num; };
🚩点此跳转到首行↩︎
参考博客
- C++构造函数之默认构造函数
- C++默认构造函数——深入理解
- 对C++默认构造函数的一点重要说明
- 拷贝构造函数
- 委托构造函数详解,小白也可以看懂
- 待定引用
- 待定引用
- 待定引用