一、对象初始化列表
1.1 对象初始化列表的原因
- 如果我们有一个类成员.它本身是一个类或者是一个结构,而且这个成员它只有一个带参数 的构造函数,没有默认构造函数。这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果役有初始化列表,那么他将无法完成第一步.就会报错。
- 类成员中若有const修饰.必须在对象初始化的时候给const int m赋值当类成员中含有const对象时,或者是一个引用时,他们也必须要通过成员初始化列表进行初始化。因为这两种对象要在声明后马上初始化,而在构造函数中.做的是对他们的赋值,这样是不被允许的。如果类的属性里面有一个const属性,那么一定要初始化
1.2 对象初始化列表的语法
Constructor::Constructor():m1(v1),m2(v1,v2),m3(v3){
//some opertation
}
二、构造函数初始化列表例子
2.2 例一
代码情景:在B类中组合了A类对象,且A类对象使用了有参数构造函数
#include <iostream>
using namespace std;
class A
{
public:
A(int _a) {
a = _a;
cout << "构造函数: " << "a " << a << endl;
}
~A(){
cout << "析构函数: " << "a " << a << endl;
}
private:
int a;
};
class B
{
public:
//构造函数初始化列表 解决在B类中组合了一个其他类的对象,且该类对象使用了有参数构造函数
//根据构造函数的调用规则,写了构造函数一定要用,所以没有初始化A
//新的语法就是构造函数的初始化列表
B(int _b1, int _b2):a1(1),a2(2),c(0){
}
B(int _b1, int _b2, int m, int n) :a1(m), a2(n),c(0) {
b1 = _b1;
b2 = _b2;
cout << "B的构造函数" << endl;
}
~B()
{
cout << "B的析构函数" << endl;
}
private:
int b1;
int b2;
//在B类里面包含了A的元素,但是没有机会初始化A类,没有办法分配内存空间,所以需要初始化列表
A a1;
A a2;
const int c; //如果类的属性里面有一个const属性,那么一定要初始化
};
//先执行被组合对象的构造函数
//如果组合对象有多个,按照定义顺序,而不是按照初始化列表的顺序
//析构函数和构造函数的调用顺序相反
//析构函数与被组合对象的构造顺序预定义顺序有关系,与初始化列表顺序没有关系
void objplay() {
//1 参数传递
B obj(1, 2, 3, 4);
//2 调用顺序
cout << "finish" << endl;
}
int main()
{
objplay();
system("pause");
return 0;
}
2.2.1执行结果
先执行被组合对象的构造函数
如果组合对象有多个,按照定义顺序,而不是按照初始化列表的顺序
析构函数和构造函数的调用顺序相反
析构函数与被组合对象的构造顺序预定义顺序有关系,与初始化列表顺序没有关系
2.2 例二(强化练习)
强烈介意自行思考!若结果与正确答案不同,建议分步调试理清思路!!
#include <iostream>
using namespace std;
class ABCD
{
public:
ABCD(int a, int b,int c) {
this->a = a;
this->b = b;
this->c = c;
cout << "ABCD有参数构造函数"<< " a:" << a << " b:" << b << " c:" << c << endl;
}
~ABCD() {
cout << "ABCD析构函数" << " a:" << a << " b:" << b << " c:" << c << endl;
}
int getA() {
return this->a;
}
private:
int a;
int b;
int c;
};
//在一个类中使用另一个类,需要初始化列表
class MyE
{
public:
MyE():abcd_1(1,2,3),abcd_2(4,5,6),m(100){
cout << "MyE的无参数构造函数" << endl;
}
MyE(const MyE & obj) :abcd_1(7, 8, 9), abcd_2(10, 11, 12), m(100) {
cout << "MyE的拷贝构造函数" << endl;
}
~MyE() {
cout << "~MyE()" << endl;
}
public:
//构造与析构只与定义顺序有关,与初始化列表顺序无关!!
ABCD abcd_2; //C++编译器不知道如何构造,需要初始化列表
ABCD abcd_1;
const int m; //存在const修饰变量的时候一定要初始化列表
};
// doThing(MyE my1)作用:在MyE类中调用ABCD类中的getA()方法
int doThing(MyE my1) {
cout << "doThing_my1.abcd_1.getA(): " << my1.abcd_1.getA() << endl;
return 0;
}
//创建一个MyE类并调用doThing函数
int run2() {
//调用无参数构造函数
MyE my2;
//调用拷贝构造函数
doThing(my2);
return 0;
}
int main()
{
//分析run2的运行步骤
run2();
system("pause");
return 0;
}