Menu
CoddyTech

构造函数初始化列表

本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 22 课,共 104 课。

你已经在前面的课中见过冒号语法,例如 Player(std::string n, int h) : name(n), health(h) {}。这称为成员初始化列表,也是在 C++ 中初始化成员的首选方式。

初始化列表位于构造函数的参数列表之后,以冒号开头。每个成员都直接用对应的值初始化,并用逗号分隔:

class Rectangle {
    int width;
    int height;
    const int id;
    int& reference;
public:
    Rectangle(int w, int h, int i, int& r) 
        : width(w), height(h), id(i), reference(r) {
        // 构造函数体(可以为空)
    }
};

为什么要使用初始化列表,而不是在构造函数体中赋值?使用赋值时,成员会先默认构造,然后再赋予新值。使用初始化列表时,成员会直接用正确的值构造出来,效率更高,有时也是必需的。

某些成员必须使用列表进行初始化:

  • const 成员,在构造后无法赋值
  • 引用成员必须在初始化时绑定
  • 没有默认构造函数的成员
class Player {
    const int maxHealth;    // 必须使用初始化列表
    std::string name;
public:
    // 这样写可以
    Player(int max, std::string n) : maxHealth(max), name(n) {}
    
    // 这样写无法编译:
    // Player(int max) { maxHealth = max; }  // 错误!
};

成员会按照它们在类中声明的顺序初始化,而不是按照它们在初始化列表中的顺序。始终按照声明顺序编写初始化列表,避免混淆。

challenge icon

挑战

简单

让我们为游戏引擎构建一个配置系统,展示成员初始化列表在什么情况下以及为什么必不可少。你将创建一个 GameConfig 类,其中的成员必须使用初始化列表语法进行初始化。

你将创建两个文件来组织代码:

  • GameConfig.h:定义一个用于存储游戏设置的 GameConfig 类。你的类应包含:
    • 一个 const std::string gameName:游戏标题,创建后不能更改
    • 一个 const int maxPlayers:最大玩家人数,在构造时确定
    • 一个 int& difficultyRef:对外部难度设置的引用
    • 一个 int screenWidth 和一个 int screenHeight:用于显示设置的普通成员
    • 一个接受所有必要参数的构造函数,并使用初始化列表初始化每个成员。初始化列表中的顺序应与成员在类中的声明顺序一致
    • 一个 display() 方法,按以下格式输出配置:
      Game: <gameName>
      Max Players: <maxPlayers>
      Difficulty: <difficultyRef value>
      Resolution: <screenWidth>x<screenHeight>
  • main.cpp:从输入中读取配置值,并创建一个 GameConfig 对象。你需要:
    • 从输入中读取游戏名称(字符串)、最大玩家人数(int)、难度(int)、宽度(int)和高度(int),每项各占一行
    • 创建一个本地 int 变量来存储难度,供配置对象引用
    • 使用初始化列表构造函数创建一个 GameConfig 对象
    • 调用 display() 显示初始配置
    • 直接修改难度变量(将它乘以 2)
    • 输出 "After difficulty change:"
    • 再次调用 display(),显示引用如何反映更新后的值

这个挑战说明了初始化列表为什么重要:你的 const 成员和引用成员不能在构造函数体中赋值,必须在初始化列表中进行初始化。引用成员还展示了对原始变量的修改如何通过配置对象反映出来。

使用 #include "GameConfig.h" 在 main.cpp 中包含头文件。

亲手试试

#include <iostream>
#include <string>
#include "GameConfig.h"

using namespace std;

int main() {
    // 读取输入值
    string gameName;
    getline(cin, gameName);
    
    int maxPlayers;
    cin >> maxPlayers;
    
    int difficulty;
    cin >> difficulty;
    
    int width;
    cin >> width;
    
    int height;
    cin >> height;
    
    // TODO: 使用初始化列表构造函数创建 GameConfig 对象
    // 构造函数应接收:gameName、maxPlayers、difficulty(按引用传递)、width、height
    
    // TODO: 调用 display() 显示初始配置
    
    // TODO: 直接修改 difficulty 变量(将其乘以 2)
    
    // TODO: 输出 "After difficulty change:"
    
    // TODO: 再次调用 display() 显示更新后的配置
    
    return 0;
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: C++ 在线编译器