引言
在c++11标准中,引入了委托构造函数和继承构造函数这两个重要的特性。这些特性不仅提升了代码的性能,还增强了代码的可读性和可维护性。对于初学者来说,理解和掌握这些特性是迈向高级c++编程的关键一步。本文将详细介绍委托构造函数和继承构造函数的基本概念、使用方法以及实际应用场景,帮助你从入门到精通。
一、委托构造函数
1.1 委托构造函数的定义与作用
委托构造函数是c++11引入的一个特性,它允许一个构造函数调用同一个类中的另一个构造函数来完成对象的初始化。这种特性可以减少代码冗余,提高代码的可维护性,同时也使得代码结构更加清晰。例如,在一个类中可能有多个构造函数,它们之间存在一些重复的初始化代码,使用委托构造函数可以避免这些重复代码的出现。
1.2 委托构造函数的语法
委托构造函数的语法格式如下:
class myclass {
public:
// 目标构造函数
myclass(int param1, int param2) {
// 构造函数的具体实现
}
// 委托构造函数
myclass(int param) : myclass(param, 0) {
// 委托给另一个构造函数完成初始化
}
};
在上述代码中,第一个构造函数接受两个参数,而第二个构造函数只接受一个参数。第二个构造函数使用了初始化列表的方式,通过委托给第一个构造函数来完成对象的初始化。
1.3 委托构造函数的使用示例
下面通过一个具体的例子来详细解析委托构造函数的使用:
#include <iostream>
using namespace std;
class test {
public:
test() {};
test(int max) {
this->m_max = max > 0 ? max : 100;
}
test(int max, int min) : test(max) {
this->m_min = min > 0 && min < max ? min : 1;
}
test(int max, int min, int mid) : test(max, min) {
this->m_middle = mid < max && mid > min ? mid : 50;
}
int m_min;
int m_max;
int m_middle;
};
int main() {
test t(90, 30, 60);
cout << "min: " << t.m_min << ", middle: " << t.m_middle << ", max: " << t.m_max << endl;
return 0;
}
在这个例子中,test(int max, int min) 构造函数委托给 test(int max) 构造函数,test(int max, int min, int mid) 构造函数委托给 test(int max, int min) 构造函数,这样可以避免在多个构造函数中重复初始化 m_max 和 m_min。
1.4 委托构造函数的注意事项
- 避免形成闭环:委托构造函数的链式调用不能形成一个闭环(死循环),否则会在运行期抛异常。例如:
class myclass {
public:
myclass(int param1) : myclass(param1, 0) {
// 委托给另一个构造函数完成初始化
}
myclass(int param1, int param2) : myclass(param1) {
// 错误:形成了闭环
}
};
- 多层链式调用建议写在初始化列表中:如果要进行多层构造函数的链式调用,建议将构造函数的调用写在初始列表中而不是函数体内部,否则编译器会提示形参的重复定义。例如:
class test {
public:
test(int max) {
this->m_max = max > 0 ? max : 100;
}
test(int max, int min) {
test(max); // 错误,编译器会报错,提示形参max被重复定义
this->m_min = min > 0 && min < max ? min : 1;
}
};
- 避免重复初始化变量:在初始化列表中调用了委托构造函数初始化某个类成员变量之后,就不能在初始化列表中再次初始化这个变量了。例如:
class test {
public:
test(int max, int min) : test(max), m_max(max) {
// 错误,使用了委托构造函数就不能再次m_max初始化了
this->m_min = min > 0 && min < max ? min : 1;
}
};

二、继承构造函数
2.1 继承构造函数的定义与作用
在c++11之前,如果基类有多个构造函数,派生类需要为自己需要用到的每一个基类构造函数编写对应的构造函数,即使这些派生类构造函数只是简单地将参数传递给基类构造函数。这不仅增加了代码量,也提高了维护成本。继承构造函数允许派生类继承基类的所有构造函数,从而无需在派生类中显式定义这些构造函数。这样做可以显著减少代码重复,使得派生类的编写更加简洁明了。
2.2 继承构造函数的语法
继承构造函数的语法格式如下:
class base {
public:
base() {
// 默认构造函数的实现
}
base(int value) {
// 带参数的构造函数实现
}
};
class derived : public base {
public:
using base::base; // 继承基类的所有构造函数
};
在这个示例中,通过在派生类中使用 using base::base; 语句,derived 类自动继承了 base 类的所有构造函数。不需要在 derived 类中显式定义这些构造函数,就可以像使用 base 类的构造函数那样使用它们来初始化 derived 类的对象。
2.3 继承构造函数的使用示例
下面通过一个具体的例子来详细解析继承构造函数的使用:
#include <iostream>
#include <string>
using namespace std;
class base {
public:
base(int i) : m_i(i) { }
base(int i, double j) : m_i(i), m_j(j) { }
base(int i, double j, string k) : m_i(i), m_j(j), m_k(k) { }
int m_i;
double m_j;
string m_k;
};
class child : public base {
public:
using base::base;
};
int main() {
child c(520, 13.14, "i love you");
cout << "int: " << c.m_i << ", double: " << c.m_j << ", string: " << c.m_k << endl;
return 0;
}
通过测试代码可以看出,在子类中初始化从基类继承的类成员,使用继承构造函数可以避免在子类中重新定义和基类一致的构造函数,使得代码更加精简。
2.4 继承构造函数的注意事项
- 同名构造函数冲突:如果从多个基类中继承了相同的构造函数(即形参列表完全相同),则程序将产生错误。例如:
struct base1 {
base1() = default;
base1(const std::string&);
base1(std::shared_ptr<int>);
};
struct base2 {
base2() = default;
base2(const std::string&);
base2(int);
};
// 错误: d1 试图从两个基类中都继承d1::d1(const string&)
struct d1 : public base1, public base2 {
using base1::base1; //从 base1 继承构造函数
using base2::base2; //从 base2 继承构造函数
};
在这种情况下,派生类必须为该构造函数定义它自己的版本:
struct d2 : public base1, public base2 {
using base1::base1; //从 base1 继承构造函数
using base2::base2; //从 base2 继承构造函数
// d2 必须自定义一个接受 string 的构造函数
d2(const string& s) : base1(s), base2(s) { }
d2() = default; // 一旦 d2 定义了它自己的构造函数,则必须出现
};
- 默认实参不继承:当一个基类构造函数含有默认实参时,这些实参并不会被继承。相反,派生类将获得多个继承的构造函数,其中每个构造函数分别省略掉一个含有默认实参的形参。例如,如果基类有一个接受两个形参的构造函数,其中第二个形参含有默认实参,则派生类将获得两个构造函数:一个构造函数接受两个形参(没有默认实参);另一个构造函数只接受一个形参,它对应于基类中最左侧的没有默认值的那个形参。

三、总结
委托构造函数和继承构造函数是c++11中非常强大的特性,它们为c++程序员提供了更多的编程选择和优化机会。通过使用委托构造函数,我们可以减少代码冗余,提高代码的可维护性;而继承构造函数则可以简化派生类构造函数的编写,提高代码的复用性。在实际编程中,合理运用这些特性可以让我们的代码更加高效、安全和易于理解。希望本文能够帮助你更好地理解和掌握c++11中的委托构造函数和继承构造函数,从而提升你的c++编程水平。
到此这篇关于c++11委托构造函数和继承构造函数:从入门到精通的文章就介绍到这了,更多相关c++11委托构造函数和继承构造函数内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论