cpp_initialize_list - ShenYj/ShenYj.github.io GitHub Wiki

初始化列表

特点

  • 一种便捷的初始化成员变量的方式
  • 只能用在构造函数中
  • 初始化顺序只跟成员变量的声明顺序有关

代码

struct Person {

    int m_age;
    int m_height;

    Person(int age, int height) :m_age(age), m_height(height) { }
};

等价于

struct Person {

    int m_age;
    int m_height;

    Person(int age, int height) {
        m_age = age;
        m_height = height;
    }
};

并且执行效率也是一样的

初始化列表与默认参数配合使用

struct Person {

    int m_age;
    int m_height;

    Person(int age = 0, int height = 0) :m_age(age), m_height(height) { }
};

如果函数声明和实现是分离的

  • 初始化列表只能写在函数的实现中
  • 默认参数只能写在函数的声明中

代码

struct Person {
    int m_age;
    int m_height;
    /// 声明
    Person(int age = 0, int height = 0);
};

Person:: Person(int age, int height) :m_age(age), m_height(height) { }

构造函数的相互调用

代码

struct Person {
    int m_age;
    int m_height;

    Person() :Person(0, 0) { }
    Person(int age, int height) :m_age(age), m_height(height) {}
};

构造函数调用构造函数,不能直接调用,必须通过初始化列表调用

错误代码

struct Person {
    int m_age;
    int m_height;

    Person() {
        /// 相当于创建了一个新的Person 对象
        Person(0, 0)
     }
    Person(int age, int height) :m_age(age), m_height(height) {}
};

父类的构造函数

  • 子类的构造函数默认会调用父类的无参构造函数

    struct Person {
        int m_age;
    
        Person() {
            cout << "Person::Person()" << endl;
        }
    
        Person(int age) {
            cout << "Person::Person()int age" << endl;
        }
    };
    
    struct Student: Person {
        int m_no;
    
        Student() {
            cout << "Student::Student()" << endl;
        }
    };
    
    int main() {
        /// 先调用父类构造函数 Person(),然后在调用自己的构造函数
        Student student;
    }
  • 如果子类的构造函数显式地调用了父类的有参构造函数,就不会再去默认调用父类的无参构造函数

  • 如果父类缺少无参构造函数,子类的构造函数必须显式调用父类的有参构造函数

class Person {
    int m_age;

public:
    Person(int age) {
        cout << "Person::Person()int age" << endl;
    }
};

class Student: Person {
    int m_no;
public:
    /// 由于是class 默认权限 private, m_age在 Student是无法直接访问的, 所以通过初始化列表中调用Person的自定义构造函数来初始化m_age
    Student(int age, int no) :m_no(no), Person(age) {
        cout << "Student::Student()" << endl;
    }
};

int main() {
    Student student(18, 34);
}

构造、析构顺序

int main() {
    {
        Student student;
    }
    getchar()
    return 0;
}

构造、析构的调用顺序

  1. 父类构造
  2. 子类构造
  3. 子类析构
  4. 父类析构
⚠️ **GitHub.com Fallback** ⚠️