YouTube视频链接
C++的成员初始化列表
本文是ChernoP35视频的学习笔记。
我们在编写一个类并向该类添加成员(变量)时,通常需要某种方式对这些成员(变量)进行初始化。
构造函数中
通常有两种方法,第一种是我们可以在构造函数中初始化一个类成员。
如下Main.cpp代码
#include<iostream>
#include<string>
class Entity
{
private:
std::string m_Name;
public:
Entity()
{
m_Name = "Unknown";
}
Entity(const std::string& name)
{
m_Name = name;
}
const std::string& GetName() const { return m_Name; }
};
int main()
{
Entity e0;
std::cout << e0.GetName() << std::endl;
Entity e1("Cherno");
std::cout << e1.GetName() << std::endl;
std::cin.get();
}
运行程序发现打印了unknown和Cherno。
成员初始化列表
第二种我们可以通过成员初始化列表来实现,若我们新增一个成员m_Score,只需要加一个逗号然后写上这个新成员。在成员初始化列表中这些变量的顺序要和成员变量声明时的顺序一致。
class Entity
{
private:
std::string m_Name;
int m_Score;
public:
Entity()
:m_Name("Unknown"),m_Score(0)
{
}
Entity(const std::string& name)
{
m_Name = name;
}
const std::string& GetName() const { return m_Name; }
};
我们也可以改变赋值的方法,用括号替换等号,然后把它移到列表中。
二者区别
这两种方法在特定类的情况下会有所区别。
class Entity
{
private:
std::string m_Name;
int x, y, z;
public:
Entity()
: x(0),y(0),z(0)
{
m_Name = "Unknown";
//等价于m_Name =std::string("Unknown");
}
};
如上代码中的m_Name对象会被构造两次,一个是使用默认构造函数,另一个是使用Unknown参数(初始化的构造函数)。结果是第一个直接被扔掉,造成性能的浪费。
我们新增Example类,有一个不带参的构造函数和一个带参数x的构造函数,然后把Example类作为Entity实际的类成员。将m_Example设置为Example类对象,有一个参数8。然后创建一个Entity对象的实例e0,使用这个默认构造函数。运行程序发现创建了两个Entity,一个是无参的,一个是有整型参数的。一个是在成员变量的区域Example m_Example;,一个是在m_Example = Example(8);,创建了一个新的Example实例,然后把它赋值给m_Example。
若我们把它移到初始化列表中,我们可以写成:m_Example(Example(8)),也可以写成:m_Example(8)。运行构造函数发现只创建了一个实例。
综上我们应到使用第二种成员初始化列表,不使用它则会浪费性能。