c++初始化列表

本文探讨了C++初始化列表的用途,通过实验验证了使用初始化列表并不会调用默认构造函数。初始化列表的主要作用包括:1) 初始化父类,当父类没有默认构造函数时,必须在子类构造函数中使用初始化列表;2) 初始化常量成员和引用,由于这些变量只能在构造函数中初始化,不能在类体内赋值。此外,初始化顺序遵循变量定义顺序或类继承顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在网上看到许多类似的博客内容,许多都是转发的,我不知道他们验证过没有,反正我试了之后发现,这根本不对,原内容如下:
在这里插入图片描述
我持着怀疑的态度去验证,发现即使用大括号来初始化,也不会调用默认构造函数,代码如下(没有任何输出):

class Animal
{
public:
	Animal() { cout << "调用我了没?" << endl; }
	/*Animal(int weight, int height) : //方法1
		m_weight(weight),
		m_height(height)
	{
	}*/
	Animal(int weight, int height) //方法2
	{
		m_weight=weight;
		m_height=weight;
	}
private:
	int m_weight;
	int m_height;
};
int main()
{
	Animal a(2,3);
}

然后我又用其它方法验证:对上述方法1和方法2,主函数改动如下:

int main()
{
	clock_t _start, _stop;
	_start = clock();
	
	for (int i = 0; i < 10000000; i++)
	{
		Animal a(2,3);
	}
	_stop = clock();
	cout << (double) ( _stop - _start ) / CLOCKS_PER_SEC << endl;
}

经过多次运行,两种方法的时间都大致为0.238秒左右,并没有较大波动,也就是说,使用方法2,并没有调用默认构造函数来浪费额外的时间。

那么,方法1,也就是初始化列表的作用是什么呢?据我的理解,有如下两点:
1、初始化父类
现在给父类加一个派生类Dog:

class Animal
{
public:
	Animal() { cout << "调用我了没?" << endl; }
	/*Animal(int weight, int height) : //方法1
		m_weight(weight),
		m_height(height)
	{
	}*/
	Animal(int weight, int height) //方法2
	{
		m_weight=weight;
		m_height=weight;
	}
private:
	int m_weight;
	int m_height;
};	

class Dog :public Animal
{
public:
	Dog(int a, int b)da(a), db(b) { };
	~Dog() {};
	
private:
	int da, db;
};

此时如果,main函数里面像下面这么写肯定没问题:

int main()
{
	Dog d(2,3);
}

但如果把方法1上面的那个无参构造函数(作用等于默认构造函数)给注释掉,那么就会报错,错误为无法找到父类的默认构造函数,那么怎么办,此时初始化列表的第一个作用就出来了, 可以给Dog类这么加:

class Dog :public Animal
{
public:
	Dog(int a, int b) :Animal(a, b), da(a), db(b) { };
	~Dog() {};
	
private:
	int da, db;
};

注意,如果进入大括号,则意味着父类已经初始化完,因此只能这么干。
这里再啰嗦两句初始化顺序的问题,具体就不用代码展开来试验了,已经我都验证过:初始化列表的初始化顺序与变量定义的顺序一致或类继承顺序一致,如果变量初始化时用到了位于同一列表的其它刚刚被初始化的变量,那这点尤为要注意。

2、初始化列表的第二个作用:
这个简单说一下,就是可以用来初始化类中的const常量和初始化引用等,因为const的量和引用这种只能被初始化一次,后面就不能更改了,因此只能在初始化列表中解决。而且不在这里解决,编译都过不去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值