C++11 中引入的委托构造函数是一种特殊的构造函数,它允许一个构造函数调用同一个类中的另一个构造函数来初始化对象。这种构造函数在声明时使用符号后跟其他构造函数的初始化列表,而不是在函数体内调用。这种特性可以减少代码冗余,提高代码的可维护性,同时也使得代码结构更加清晰。本文将详细介绍委托构造函数的定义、使用方法、使用场景以及注意事项。
委托构造函数的语法格式如下:
class MyClass {
public:
MyClass(int param1, int param2) {
// 构造函数的具体实现
}
MyClass(int param) : MyClass(param, 0) {
// 委托给另一个构造函数完成初始化
}
};
在上述代码中,第一个构造函数接受两个参数,而第二个构造函数只接受一个参数。第二个构造函数使用了初始化列表的方式,通过委托给第一个构造函数来完成对象的初始化。
class MyClass {
public:
MyClass(int param1, int param2) : param1_(param1), param2_(param2) {
// 正确的初始化
}
MyClass(int param) : MyClass(param, 0), param_(param) { // 错误:不能同时使用委托构造函数和成员初始化列表
// 委托给另一个构造函数完成初始化
}
private:
int param1_;
int param2_;
int param_;
};
class MyClass {
public:
MyClass(int param1, int param2, int param3) : param1_(param1), param2_(param2), param3_(param3) {
// 正确的初始化
}
MyClass(int param1, int param2) : MyClass(param1, param2, 0) {
// 委托给另一个构造函数完成初始化
}
MyClass(int param1) : MyClass(param1, 0) {
// 委托给另一个构造函数完成初始化
}
private:
int param1_;
int param2_;
int param3_;
};
但以下代码是错误的,因为它形成了一个闭环:
class MyClass {
public:
MyClass(int param1) : MyClass(param1, 0) {
// 委托给另一个构造函数完成初始化
}
MyClass(int param1, int param2) : MyClass(param1) {
// 错误:形成了闭环
}
};
C++11 引入委托构造函数的原因主要包括以下几点:
下面我们通过两个示例来详细解析委托构造函数的使用。
class MyClass {
public:
MyClass(int a, double b) : a_(a), b_(b) {
// 构造函数的具体实现
std::cout << "MyClass(int, double) called" << std::endl;
}
MyClass(int a) : MyClass(a, 0.0) {
// 委托给另一个构造函数完成初始化
std::cout << "MyClass(int) called" << std::endl;
}
MyClass(int a, double b, std::string c) : a_(a), b_(b), c_(std::move(c)) {
// 构造函数的具体实现
std::cout << "MyClass(int, double, std::string) called" << std::endl;
}
private:
int a_;
double b_;
std::string c_;
};
在这个例子中,MyClass(int a) 构造函数委托给 MyClass(int a, double b) 构造函数,将 b 参数设置为 0.0。这样可以避免在多个构造函数中重复初始化 a 和 b。
class Person {
public:
Person(const std::string& name, int age) : name_(name), age_(age) {
std::cout << "Person(const std::string&, int) called" << std::endl;
}
Person(const std::string& name) : Person(name, 0) {
std::cout << "Person(const std::string&) called" << std::endl;
}
Person() : Person("", 0) {
std::cout << "Person() called" << std::endl;
}
void printInfo() const {
std::cout << "Name: " << name_ << ", Age: " << age_ << std::endl;
}
private:
std::string name_;
int age_;
};
在这个例子中,Person(const std::string& name) 构造函数委托给 Person(const std::string& name, int age) 构造函数,将 age 参数设置为 0。Person() 构造函数则委托给 Person(const std::string& name, int age) 构造函数,将 name 参数设置为 "",age 参数设置为 0。
假设有一个类 ComplexClass,它有多个成员变量和多个构造函数,我们可以使用委托构造函数来简化初始化逻辑:
class ComplexClass {
public:
ComplexClass(int a, double b, std::string c, bool d) : a_(a), b_(b), c_(std::move(c)), d_(d) {
std::cout << "ComplexClass(int, double, std::string, bool) called" << std::endl;
}
ComplexClass(int a, double b, std::string c) : ComplexClass(a, b, c, false) {
std::cout << "ComplexClass(int, double, std::string) called" << std::endl;
}
ComplexClass(int a, double b) : ComplexClass(a, b, "", false) {
std::cout << "ComplexClass(int, double) called" << std::endl;
}
ComplexClass(int a) : ComplexClass(a, 0.0, "", false) {
std::cout << "ComplexClass(int) called" << std::endl;
}
private:
int a_;
double b_;
std::string c_;
bool d_;
};
在这个例子中,多个构造函数通过委托构造函数的方式,最终调用最完整的构造函数 ComplexClass(int a, double b, std::string c, bool d),这样可以避免在每个构造函数中重复初始化成员变量。
在使用委托构造函数时,需要注意以下几点:
class MyClass {
public:
MyClass() : MyClass() { // 错误:形成了闭环
}
};
class MyClass {
public:
MyClass(int a, double b) : a_(a), b_(b) {
}
MyClass(double b, int a) : MyClass(a, b) {
}
private:
int a_;
double b_;
};
但以下代码是错误的,因为它违反了成员变量的声明顺序:
class MyClass {
public:
MyClass(int a, double b) : a_(a), b_(b) {
}
MyClass(double b, int a) : MyClass(b, a) { // 错误:违反了成员变量的声明顺序
}
private:
int a_;
double b_;
};
class MyClass {
public:
MyClass(int a, double b) : a_(a), b_(b) {
}
MyClass(std::string c) : MyClass(c.length(), 0.0) {
}
private:
int a_;
double b_;
};
在这个例子中,MyClass(std::string c) 构造函数将 std::string 对象的长度传递给 MyClass(int a, double b) 构造函数。
委托构造函数是 C++11 的一项重要特性,它通过允许一个构造函数调用同一个类中的另一个构造函数来初始化对象,从而减少了代码冗余,提高了代码的可维护性和清晰度。合理使用委托构造函数可以简化类的构造逻辑,使代码更加简洁和易于管理。同时,理解和掌握委托构造函数的使用,也是提升 C++ 编程技能的重要一步。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。