C++_复习05(构造函数的初始化列表)

一、对象初始化列表

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;
}

2.2.1 运行结果

发布了27 篇原创文章 · 获赞 3 · 访问量 3339

猜你喜欢

转载自blog.csdn.net/weixin_40977054/article/details/102518778