什么时候需要初始化列表?

在刚接触QT的时候我们都会看到自动生成的主界面构造函数如下:

MainWidget::MainWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWidget)
{

}

这边使用的就是初始化列表,初始化列表主要用于以下几种情况:
第一种:
类B中包含另一个类A的对象a,但是类A的构造函数含有参数例如A(int x),那么当类B初始化时,若没有初始化列表,无法正常初始化B,正确做法是将B的构造函数写为B():a(x)。
代码如下:

#include "iostream"
using namespace std;
class A
{
public:
	A(int x){
		cout << "A Create" << endl;
	};
};
class B
{
public:
	B():a(1){    
		cout << "B Create" << endl;
	};
private:
	A a; 
};

int _tmain(int argc, _TCHAR* argv[])
{
	B test;
	std::getchar();
	return 0;
}

运行效果:
A Create
B Create
如果将初始化列表a(1)删去,编译将出错。

第二种:
当类成员中含有const修饰的变量时,在声明时就需要初始化,在构造函数中只能进行赋值,并不是在初始化阶段,因此这种情况必须要用到初始化列表来初始化,示例代码如下:

#include "iostream"
using namespace std;

class A
{
private:
	const int a;
public:
	A() :a(1){
		cout << "A Create" << endl;
	}      
};

int _tmain(int argc, _TCHAR* argv[])
{
	A testA;
	std::getchar();
	return 0;
}

运行效果:
A Create
如果将初始化列表a(1)删去,编译将出错,提示常量a没有初始化。

第三种:
当类成员中含有引用(&)的变量时,在声明时就需要初始化,在构造函数中只能进行赋值,并不是在初始化阶段,因此这种情况必须要用到初始化列表来初始化,示例代码如下:

using namespace std;

class B
{
private:
	int &b;                   
public:
	B(int b) :b(b){
		cout << "B Create" << endl;
	}      
};


int _tmain(int argc, _TCHAR* argv[])
{
	B testB(1);
	std::getchar();
	return 0;
}

运行效果:
B Create
如果将初始化列表b(b)删去,编译将出错,提示构造函数未提供&b的初始化设定。

第四种:
当类为继承类,且想要初始化父类成员时,需要使用初始化列表,示例代码如下:

using namespace std;

class A{
public:
	A(){};
	A(int x) :int_x(x) { cout << "Creat A" << endl; };
	void printx(){
		cout << int_x << endl;
	}

	int int_x;
};

class B :public A{
public:
	B() :A(1){
		//B() : int_x(1){//错误1
		//A(1); //错误2
		cout << "Creat B" << endl;
	};
};

int _tmain(int argc, _TCHAR* argv[])
{
	A *p = new B();
	p->printx();
	std::getchar();
	return 0;
}

运行效果:
Creat A
Creat B
1
如果将B的构造函数初始化列表写为错误1,那么编译不通过,初始化冲突,到底是父类初始化还是子类初始化?
如果将父类A的构造函数显式调用即错误2,并且B构造函数不使用初始化列表,那么打印出的int_x将是随机值。原因在于在B执行构造函数的时候,已经隐式的调用A的无参构造函数,此时int_x已经被初始化,此时再次显示调用A的有参构造函数已经无法再次初始化int_x,因此并没有被赋值,所以此时打印出来的是随机值。

第五种:
需要提升编译效率的情况,初始化列表可以使得变量在初始化阶段的同时进行赋值,而不使用初始化列表的情况则需要进行初始化和赋值两个阶段,这对于大型类来说效率有很大的提升。
另外,需要注意的是,初始化列表并不是变量初始化顺序的依据,初始化顺序依然是以声明的顺序为准。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值