Menu
CoddyTech

委托构造函数

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

当你有多个构造函数共享相同的初始化逻辑时,可以使用委托构造函数来避免代码重复。委托构造函数会在其初始化列表中调用同一个类的另一个构造函数。

class Player {
    std::string name;
    int health;
    int level;
public:
    // 主构造函数负责实际工作
    Player(std::string n, int h, int lvl) 
        : name(n), health(h), level(lvl) {}
    
    // 委托给主构造函数
    Player(std::string n) : Player(n, 100, 1) {}
    
    // 默认构造函数也会委托给主构造函数
    Player() : Player("Unknown") {}
};

委托在初始化列表中完成,使用类名后跟参数。调用 Player() 时,它会委托给 Player(std::string),后者再委托给三参数构造函数。调用链会从目标构造函数开始,返回到最初的构造函数。

有一条重要规则:委托构造函数的初始化列表中不能有其他成员。委托必须是唯一的项目:

class Item {
    int id;
    int value;
public:
    Item(int i, int v) : id(i), value(v) {}
    
    // 错误!不能同时使用委托构造和成员初始化。
    // Item(int i) : Item(i, 0), id(i) {}
    
    // 正确:只使用委托构造。
    Item(int i) : Item(i, 0) {}
};

委托构造函数有助于将初始化逻辑集中在一处,让代码更易于维护,也能减少重复代码导致的错误。

challenge icon

挑战

简单

让我们构建一个连接设置系统,演示如何通过串联构造函数调用,让委托构造函数避免代码重复。

你将创建两个文件来整理代码:

  • Connection.h:定义一个表示网络连接的 Connection 类,并提供多种配置选项。你的类应包含:
    • 私有成员:host(字符串)、port(int)、timeout(以秒为单位的 int)和 secure(bool)
    • 一个主构造函数,接收全部四个参数,并使用初始化列表初始化所有成员。这个构造函数应打印 "Connection configured: <host>:<port>"
    • 一个只接收 host 和 port 的构造函数,它委托给主构造函数,其中 timeout 默认为 30,secure 默认为 false
    • 一个只接收 host 的构造函数,它委托给双参数构造函数,其中 port 默认为 80
    • 一个默认构造函数,它委托给单参数构造函数,其中 host 默认为 "localhost"
    • 一个 getInfo() 方法,返回格式为 "<host>:<port> (timeout: <timeout>s, secure: <yes/no>)" 的字符串
  • main.cpp:通过使用不同的构造函数创建连接,展示委托调用链。读取输入中的主机名和端口号(分别占一行),然后:
    • 使用默认构造函数创建一个 Connection
    • 使用输入中的主机创建一个 Connection
    • 使用输入中的主机和端口创建一个 Connection
    • 使用输入中的主机、输入中的端口、值为 60 的超时时间,以及设为 true 的安全状态,创建一个 Connection
    • 为每个连接打印 getInfo(),每行一个

委托调用链如下:默认构造函数调用单参数构造函数,单参数构造函数调用双参数构造函数,双参数构造函数再调用主四参数构造函数。这意味着每创建一个对象,都会打印一次 "Connection configured" 消息,而且始终由主构造函数打印。

对于 getInfo() 中的安全状态,如果 secure 为 true,就打印 "yes";否则打印 "no"。

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

亲手试试

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

using namespace std;

int main() {
    // 读取输入
    string host;
    int port;
    cin >> host;
    cin >> port;

    // TODO: 使用默认构造函数创建一个 Connection 对象

    // TODO: 只使用输入的 host 创建一个 Connection 对象

    // TODO: 使用输入的 host 和 port 创建一个 Connection 对象

    // TODO: 使用输入的 host 和 port,以及 timeout=60、secure=true 创建一个 Connection 对象

    // TODO: 每行打印一个连接的 getInfo() 结果

    return 0;
}
quiz icon自我测试

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

面向对象编程中的所有课

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