C++ 语言特性11 - 继承构造函数
一:概述
在C++中,直到C++11标准发布之前,派生类(子类)不能直接继承基类的构造函数。如果基类有多个构造函数,派生类需要显式地为每一个基类构造函数编写对应的派生类构造函数。这不仅增加了代码量,也提高了维护成本,因为基类构造函数的任何修改都需要在所有派生类中进行相应的更新。
C++11标准引入了继承构造函数的概念,允许派生类通过using
声明来继承基类的构造函数。这使得派生类可以直接使用基类的构造函数来初始化其继承的基类部分,而不需要在派生类中显式地重写或复制这些构造函数的初始化代码
二:例子
class Base {
public:
Base(int x) : value(x) {}
Base(double x) : value(static_cast<int>(x)) {}
private:
int value;
};
class Derived : public Base {
public:
using Base::Base; // 继承构造函数
// 派生类特有的成员和方法
void print() const {
std::cout << "Value: " << value << std::endl;
}
};
int main() {
Derived d1(10); // 调用 Base(10)
Derived d2(3.14); // 调用 Base(3.14)
d1.print();
d2.print();
return 0;
}
三:使用继承构造的注意事项
-
访问权限: 只有公开(public)或受保护(protected)的基类构造函数可以被派生类继承。私有(private)构造函数不能被继承。
class Base {
private:
Base(int x) {} // 私有构造函数
};
class Derived : public Base {
public:
using Base::Base; // 错误:不能继承私有构造函数
};
-
构造函数的匹配: 派生类继承的构造函数必须与基类的构造函数具有相同的参数类型和顺序。
class Base {
public:
Base(int x) {}
};
class Derived : public Base {
public:
using Base::Base; // 错误:参数类型不匹配
Derived(double x) : Base(x) {} // 尝试将double转换为int
};
-
继承构造函数的声明顺序:
using
声明必须在派生类中所有成员定义之前出现,包括构造函数和析构函数。
class Base {
public:
Base(int x) {}
};
class Derived : public Base {
public:
int value;
using Base::Base; // 错误:声明顺序不正确
};
-
参数的默认值: 基类构造函数中的默认参数值不会被继承。派生类继承的构造函数将忽略这些默认值。
class Base {
public:
Base(int x = 10) {} // 带有默认参数的构造函数
};
class Derived : public Base {
public:
using Base::Base; // 默认参数不会被继承
};
-
构造函数的重定义: 如果派生类定义了自己的构造函数,那么与基类构造函数具有相同签名的继承构造函数将被覆盖。
class Base {
public:
Base(int x) {}
};
class Derived : public Base {
public:
Derived(int x) : Base(x) {} // 重定义构造函数
using Base::Base; // 错误:与派生类的构造函数冲突
};
-
多重继承: 在多重继承的情况下,派生类可能会从多个基类继承构造函数。如果构造函数的参数列表相同,派生类需要明确指定使用哪个基类的构造函数。
class Base1 {
public:
Base1(int x) {}
};
class Base2 {
public:
Base2(int x) {}
};
class Derived : public Base1, public Base2 {
public:
using Base1::Base1; // 错误:与Base2构造函数冲突
using Base2::Base2;
};
-
继承与类模板: 在模板类中使用继承构造函数时,需要确保模板参数不会影响构造函数的可行性。
template <typename T>
class Base {
public:
Base(T x) {}
};
class Derived : public Base<int> {
public:
using Base::Base; // 错误:模板参数导致构造函数不匹配
};
-
继承构造函数与默认构造函数: 如果派生类使用了继承构造函数,编译器不会自动生成默认构造函数,除非基类也没有默认构造函数。
class Base {
public:
Base(int x) {}
};
class Derived : public Base {
public:
using Base::Base; // 没有默认构造函数
};