C++的成员初始化列表

C++的成员构造函数初始化列表:构造函数中初始化类成员的一种方式,当我们编写一个类并向该类添加成员时,通常需要某种方式对这些成员变量进行初始化。

建议应该在所有地方使用成员初始化列表进行初始化

成员初始化的方法

方法一:

正常使用{}赋值类成员变量

cpp 复制代码
class Entity
{
private:
	string m_Name;  // 第一种方法会在这使用一次默认构造函数Entity()
	int m_Score;
	Example m_example;
public:
	//第一种方法初始化
	//默认构造函数
	Entity()
	{
		m_Name = "Unknown";  // 第一种方法在构造函数时会调用两次默认构造函数
	}
	//构造函数:接受name作为参数的构造函数
	Entity(const string& name)
	{
		m_Name = name;
	}
};

方法二:

使用成员初始化列表方式

形式就是函数名后面加上冒号,对成员变量进行赋值,用括号替换等号

cpp 复制代码
class Entity
{
private:
	string m_Name; 
	int m_Score;
	Example m_example;
public:
    Entity()
		: m_example(Example(8)) // m_example(8)等价于m_example(Example(8))
	{
		//m_example = Example(8);
	}
	// 成员初始化列表方式
	// 注意:不管你怎末写初始化列表,它都会按照定义类成员的顺序进行初始化,因此要确保做成员初始化列表时,要与成员变量声明时的顺序一致
	Entity(const int score)
		: m_Name("Unknown"),m_Score(score)  // 列出想要初始化的成员,等价m_Name = "Unknown";
	{
	}
	Entity(const string& Name,const int& score)
		: m_Name(Name),m_Score(score)  // 用括号替换等号,等价m_Name = name;
	{
	}
	const string& GetName() const
	{
		return m_Name;
	}
};

注意:不管你怎末写初始化列表,它都会按照定义类成员的顺序进行初始化,因此要确保做成员初始化列表时,要与成员变量声明时的顺序一致。成员变量声明时按照m_Name,m_Score顺序,使用成员初始化列表时需要同声明顺序一致。

两种方法的差别:

在特定类,两者功能上有区别

第一种方法在构造函数时会调用两次默认构造函数

案例:

cpp 复制代码
# include <iostream>
# include <string>
using namespace std;

class Example
{
public:
	Example()
	{
		cout << "Created Entity!" << endl;
	}
	Example(int x)
	{
		cout << "Created Entity with " << x << "!" << endl;
	}

};

class Entity
{
private:
	string m_Name;  // 第一种方法会在这使用一次默认构造函数Entity()
	int m_Score;
	Example m_example;
public:
	//在特定类,两者功能上有区别
	//第一种方法初始化
	//默认构造函数
	Entity()
	{
		m_Name = "Unknown";  // 第一种方法在构造函数时会调用两次默认构造函数
		m_example = Example(8);
	}
};
int main()
{
	Entity e0;
	//cout << e0.GetName() << endl;

	/*Entity e1("Chen");
	cout << e1.GetName() << endl;*/
	cin.get();
	return 0;
}

输出结果会同时打印出Created Entity! 以及 Created Entity with 8!。由于string是一个类,因此在声明变量时就会调用默认构造函数Entity(),而在实例化对象中,也会调用一次构造函数,然后丢弃第一次的字符串,造成资源的浪费。

当使用成员初始化列表方式就不会出现这种问题。

cpp 复制代码
Entity()
		: m_example(Example(8)) // m_example(8)等价于m_example(Example(8))
	{
		m_Name = "Unknown";  // 第一种方法在构造函数时会调用两次默认构造函数
		//m_example = Example(8);
	}

总的来说:应该在所有地方使用成员初始化列表进行初始化,要不然会浪费性能,对于整型这样的基本类型,它不会被初始化,除非你通过赋值来初始化它们

整体代码:

cpp 复制代码
# include <iostream>
# include <string>
using namespace std;

class Example
{
public:
	Example()
	{
		cout << "Created Entity!" << endl;
	}
	Example(int x)
	{
		cout << "Created Entity with " << x << "!" << endl;
	}

};

class Entity
{
private:
	string m_Name;  // 第一种方法会在这使用一次默认构造函数Entity()
	int m_Score;
	Example m_example;
public:
	//在特定类,两者功能上有区别
	//第一种方法初始化
	//默认构造函数
	Entity()
		: m_example(Example(8)) // m_example(8)等价于m_example(Example(8))
	{
		m_Name = "Unknown";  // 第一种方法在构造函数时会调用两次默认构造函数
		//m_example = Example(8);
	}
	//构造函数:接受name作为参数的构造函数
	Entity(const string& name)
	{
		m_Name = name;
	}
	// 成员初始化列表方式
	// 注意:不管你怎末写初始化列表,它都会按照定义类成员的顺序进行初始化,因此要确保做成员初始化列表时,要与成员变量声明时的顺序一致
	Entity(const int score)
		: m_Name("Unknown"),m_Score(score) // 列出想要初始化的成员,等价m_Name = "Unknown";
	{
	}
	Entity(const string& Name,const int& score)
		: m_Name(Name),m_Score(score)  // 用括号替换等号,等价m_Name = name;
	{
	}
	const string& GetName() const
	{
		return m_Name;
	}
};
int main()
{
	Entity e0;
	//cout << e0.GetName() << endl;

	/*Entity e1("Chen");
	cout << e1.GetName() << endl;*/
	cin.get();
	return 0;
}
// 应该在所有地方使用成员初始化列表进行初始化,要不然会浪费性能,对于整型这样的基本类型,它不会被初始化,除非你通过赋值来初始化它们
相关推荐
️停云️34 分钟前
【滑动窗口与双指针】不定长滑动窗口
c++·算法·leetcode·剪枝·哈希
charlie11451419137 分钟前
嵌入式现代C++教程: 构造函数优化:初始化列表 vs 成员赋值
开发语言·c++·笔记·学习·嵌入式·现代c++
IT=>小脑虎1 小时前
C++零基础衔接进阶知识点【详解版】
开发语言·c++·学习
码农小韩2 小时前
基于Linux的C++学习——指针
linux·开发语言·c++·学习·算法
小L~~~2 小时前
绿盟校招C++研发工程师一面复盘
c++·面试
微露清风2 小时前
系统性学习C++-第十九讲-unordered_map 和 unordered_set 的使用
开发语言·c++·学习
_Lzk666888_2 小时前
洛谷用户2002780求关注
c++·其他
无限进步_3 小时前
【C语言&数据结构】对称二叉树:镜像世界的递归探索
c语言·开发语言·数据结构·c++·git·算法·visual studio
X***07883 小时前
C语言在嵌入式系统开发中的应用与挑战
c++
小芒果_013 小时前
整理归并排序
c++·算法·排序算法·信息学奥赛