677 字
3 分钟
C++入门 (十六) : 成员初始化列表
2026-03-23

构造函数初始化列表,是我们在构造函数中初始化类成员的一种方式。当我们编写类并向这个类添加成员的时候,通常需要用某种方式对这些成员进行初始化,这一般发生在构造函数中,我们有两种方法可以再构造函数中初始化类成员。

构造函数初始化#

一般方法#

#include <iostream>
#include <string>
#define LOG(x) std::cout << x << std::endl;
class Entity
{
private:
std::string m_Name;
public:
Entity() //Entity entity1; 调用默认构造函数,默认使用 "Unknown" 作为名称
{
m_Name = "Unknown";
}
Entity(const std::string& name) // Entity entity2("Alice"); 调用带参数构造函数,使用 "Alice" 作为名称
{
m_Name = name;
}
const std::string& GetName() const { return m_Name; };
};
int main()
{
Entity e;
LOG(e.GetName()) // "Unknown"
Entity e1("Eureka");
LOG(e1.GetName()) // "Eureka"
std::cin.get();
}

构造函数初始化列表#

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) // 相当于用括号代替等号,然后移到列表里
{
// m_Name = name;
}
const std::string& GetName() const { return m_Name; };
};
int main()
{
Entity e;
LOG(e.GetName())
Entity e1("Eureka");
LOG(e1.GetName())
std::cin.get();
}

不管你怎么写初始化列表,它都会按照类成员的定义顺序进行初始化。如果打破这个顺序,就会导致各种依赖问题。所以要确保写成员初始化列表时,保持和成员变量的声明顺序一样

为什么要使用成员初始化#

  • 代码风格原因,就是如果变量多起来的话,写在 list 里会让我们的构造函数代码非常干净而且容易阅读。
  • 功能上的区别,这个区别特定的作用在类上。
Entity()
: x(0),y(0),z(0)
{
m_Name = "Unknown"; // m_Name会被构造两次
//相当于 std::string("Unknown");
}

你创建了两个字符串,其中一个直接被抛弃了,这是性能浪费

class Example
{
public:
Example()
{
LOG("Created Entity!");
}
Example(int x)
{
std::cout << "Created Entity with " << x << "!" << std::endl;
}
};
class Entity
{
private:
std::string m_Name;
Example m_Example;
public:
Entity()
{
m_Name = std::string("Unknown");
m_Example = Example(8);
}
Entity(const std::string& name)
: m_Name(name)
{
}
const std::string& GetName() const { return m_Name; };
};
int main()
{
Entity e; // "Created Entity!"
// "Created Entity with 8"
std::cin.get();
}

这里创建了两个 Entity,一个是在private:Example m_Example;创建的,另一个是m_Example = Example(8);,在这里创建了一个新的 Example 对象,然后赋值给了 m_Example(old one),覆盖造成性能浪费。

但是如果改成移动到初始化列表中:

Entity()
: m_Example(8)
// : m_Example(Example(8))
{
m_Name = std::string("Unknown");
}

这样就只会创建一个对象。所以你应该到处使用成员初始化列表,绝对没有不使用它们的理由

C++入门 (十六) : 成员初始化列表
https://dingfengbo.vercel.app/posts/c入门/16-c的成员初始化列表/
作者
Eureka
发布于
2026-03-23
许可协议
CC BY-NC-SA 4.0