110.成员初始化列表会在什么时候用到?它的调用过程是什么?
110.成员初始化列表会在什么时候用到?它的调用过程是什么?
1.当初始化一个引用成员变量时;
struct MyClass
{
const int mya;
int& myb;
MyClass(int a, int& b) :mya(a), myb(b) {}
~MyClass() {}
};
2.当初始化一个非静态的常量成员时;
int a = 1;
class MyClass
{
public:
const int mA;
MyClass():mA(a)// 在初始化列表初始化mA的值
{
}
};
3.当调用一个基类的构造函数,而构造函数拥有一组参数时;
#include <iostream>
using namespace std;
class Base
{
public:
Base(const string& str, int i) : Bstr(str), _i(i) // 使用const引用避免复制,
{
cout << "Base Constructor" << " Bstr = " << Bstr << ", _i = " << _i << endl;
}
string Bstr;
int _i;
};
class Derived : public Base
{
public:
// 调用基类构造函数,而它拥有一组参数时,要使用成员初始化列表
Derived() : Base("DerivedStr", 200) // 这个是正确的
{
//Base::Bstr = "DerivedStr"; // 基类构造函数再次之前调用,这里赋值没有用。
//Base::_i = 200;
cout << "Derived Constructor" << endl;
}
string Dstr;
};
int main()
{
Derived d;
return 0;
}
4.当调用一个成员类的构造函数,而他拥有一组参数;
#include <iostream>
using namespace std;
class StuClass
{
public:
// 成员变量,存储了一个MemberClass对象
int studentNum;
string studentName;
int studentAge;
// 主类的构造函数,使用成员初始化列表来初始化成员变量member
StuClass(int stuNum, string stuName, int stuAge) : studentNum(stuNum), studentName(stuName), studentAge(stuAge)
{
}
};
int main()
{
// 创建一个MainClass对象,并传递参数5给MainClass的构造函数
StuClass obj(20211101, "悟空", 26);
// 输出成员变量member的值,可以看到已经被初始化为5
cout << "学号:" << obj.studentNum << ",姓名:" << obj.studentName << ",年龄:" << obj.studentAge << endl;
return 0;
}
5.成员类型是没有默认构造函数的类。
派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员;如果基类没有提供显示初始化式,则编译器隐式使用成员类型的默认构造函数,若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败。
则必须在派生类构造函数的初始化列表阶段显示调用
class A
{
public:
A(int x) //因为我们写了构造函数,所以这个类没有默认构造函数了
{
_a = x;
}
public:
int _a;
};
class Data
{
public:
Data(int year = 0, int month = 0, int day = 0) :a(0) //使用初始化列表初始化
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
A a; //创建一个类的对象
};
5.编译器会一一操作初始化列表,以适当顺序在构造函数之内安插初始化操作,并且在任何显示用户代码前。list中的项目顺序是由类中的成员声明顺序决定的,不是初始化列表中的排列顺序决定的。
参考资料来源:
阿秀