为什么这个代码:
class A
{
public:
explicit A(int x) {}
};
class B: public A
{
};
int main(void)
{
B *b = new B(5);
delete b;
}
导致以下错误:
main.cpp: In function ‘int main()’:
main.cpp:13: error: no matching function for call to ‘B::B(int)’
main.cpp:8: note: candidates are: B::B()
main.cpp:8: note: B::B(const B&)
B不应该继承A的构造函数吗?
(这是使用gcc)
如果你的编译器支持c++ 11标准,有一个构造函数继承使用using(双关语)。有关更多信息,请参阅维基百科c++ 11文章。你写的:
class A
{
public:
explicit A(int x) {}
};
class B: public A
{
using A::A;
};
这是全有或全无——你不能只继承一些构造函数,如果你这样写,你就继承了所有的构造函数。要只继承选定的构造函数,您需要手动编写各个构造函数,并根据需要从它们调用基构造函数。
从历史上看,c++ 03标准中不能继承构造函数。您需要通过自己调用基本实现来逐个手动继承它们。
对于模板化基类,请参考以下示例:
using std::vector;
template<class T>
class my_vector : public vector<T> {
public:
using vector<T>::vector; ///Takes all vector's constructors
/* */
};
这是直接来自Bjarne Stroustrup的页面:
如果你选择这样做,你仍然可以通过在派生类中继承构造函数来搬起石头砸自己的脚,在派生类中定义需要初始化的新成员变量:
struct B1 {
B1(int) { }
};
struct D1 : B1 {
using B1::B1; // implicitly declares D1(int)
int x;
};
void test()
{
D1 d(6); // Oops: d.x is not initialized
D1 e; // error: D1 has no default constructor
}
注意使用c++ 11的另一个重要特性(成员初始化):
int x = 77;
而不是
int x;
就能解决问题
下面是我如何使派生类“继承”所有父类的构造函数。我发现这是最直接的方法,因为它只是将所有参数传递给父类的构造函数。
class Derived : public Parent {
public:
template <typename... Args>
Derived(Args&&... args) : Parent(std::forward<Args>(args)...)
{
}
};
或者如果你想要一个漂亮的宏:
#define PARENT_CONSTRUCTOR(DERIVED, PARENT) \
template<typename... Args> \
DERIVED(Args&&... args) : PARENT(std::forward<Args>(args)...)
class Derived : public Parent
{
public:
PARENT_CONSTRUCTOR(Derived, Parent)
{
}
};