格式定义
在 C++11 里,委托构造函数的格式为:一个构造函数能够在其成员初始化列表里调用同一个类的其他构造函数。基本语法如下:
cpp
class ClassName {
public:
// 被委托的构造函数(目标构造函数)
ClassName(参数列表1) : 成员初始化列表1 {
// 函数体
}
// 委托构造函数
ClassName(参数列表2) : ClassName(参数列表1) {
// 委托构造函数自身的额外操作(可选)
}
};
ClassName
是类的名称。参数列表1
是被委托构造函数所需的参数。成员初始化列表1
用于初始化类的成员变量。参数列表2
是委托构造函数接收的参数,它可能和参数列表1
不同。- 在委托构造函数的成员初始化列表中,
ClassName(参数列表1)
这种形式就是调用被委托的构造函数。
使用场景
1. 减少代码重复
当一个类存在多个构造函数,且这些构造函数有部分初始化逻辑相同时,使用委托构造函数能避免代码重复,提高代码的可维护性。要是后续需要修改初始化逻辑,只需在被委托的构造函数里修改即可。
2. 提供多种初始化方式
委托构造函数允许为类提供多种不同的初始化方式,用户可以依据具体需求选择合适的构造函数,同时把核心的初始化逻辑集中在一个或几个构造函数中。
举例说明
下面是一个 Person
类的示例,展示了委托构造函数的使用:
cpp
#include <iostream>
#include <string>
class Person {
private:
std::string name;
int age;
std::string address;
public:
// 被委托的构造函数,完成所有成员的初始化
Person(const std::string& n, int a, const std::string& addr)
: name(n), age(a), address(addr) {
std::cout << "被委托的构造函数被调用" << std::endl;
}
// 委托构造函数 1:省略地址信息,使用默认地址
Person(const std::string& n, int a)
: Person(n, a, "未提供地址") {
std::cout << "委托构造函数 1 被调用" << std::endl;
}
// 委托构造函数 2:省略年龄和地址信息,使用默认值
Person(const std::string& n)
: Person(n, 0, "未提供地址") {
std::cout << "委托构造函数 2 被调用" << std::endl;
}
// 打印人员信息的函数
void printInfo() const {
std::cout << "姓名: " << name << ", 年龄: " << age
<< ", 地址: " << address << std::endl;
}
};
int main() {
// 使用委托构造函数 2 创建对象
Person p1("张三");
p1.printInfo();
std::cout << std::endl;
// 使用委托构造函数 1 创建对象
Person p2("李四", 25);
p2.printInfo();
std::cout << std::endl;
// 使用被委托的构造函数创建对象
Person p3("王五", 30, "北京市朝阳区");
p3.printInfo();
return 0;
}
代码解释
- 被委托的构造函数 :
Person(const std::string& n, int a, const std::string& addr)
是被委托的构造函数,它接收三个参数,对name
、age
和address
进行初始化。 - 委托构造函数 1 :
Person(const std::string& n, int a)
接收两个参数,省略了address
参数。在成员初始化列表中调用被委托的构造函数,并为address
提供默认值"未提供地址"
。 - 委托构造函数 2 :
Person(const std::string& n)
接收一个参数,省略了age
和address
参数。在成员初始化列表中调用被委托的构造函数,并为age
和address
提供默认值。 main
函数 :分别使用不同的构造函数创建Person
对象,并调用printInfo
函数输出对象信息。
注意事项
- 委托构造函数只能在成员初始化列表中调用其他构造函数,不能在构造函数体中调用。
- 要避免出现构造函数的循环委托,不然会导致编译错误。