继承:没有合适的默认构造函数可用
Inheritance: No appropriate default constructor available
我得到错误:没有合适的默认构造函数用于B。然而,当我给出参数ii和DONT想要调用默认构造函数时,我不明白编译器为什么要调用默认构造函数。
#include <iostream>
using namespace std;
class A {
int i;
public:
A(int ii) { i = ii; cout << "Constructor for An"; }
~A() { cout << "Destructor for An"; }
void f() const{}
};
class B {
int i;
public:
B(int ii) { i = ii; cout << "Constructor for Bn"; }
~B() { cout << "Destructor for Bn"; }
void f() const{}
};
class C:public B {
A a;
public:
C() { cout << "Constructor for Cn"; }
~C() { cout << "Destructor for Cn"; }
void f() const {
a.f();
B::f();
}
};
class D:public B {
C c;
public:
D(int ii) { B(ii); cout << "Constructor for Dn"; }
~D() { cout << "Destructor for Dn"; }
};
int main() {
D d(47);
}
应该在初始值设定项列表中调用父构造函数:
class D:public B {
C c;
public:
D(int ii) : B(ii)/* <- */ { cout << "Constructor for Dn"; }
~D() { cout << "Destructor for Dn"; }
};
注意/*<-*/议论这需要改变。
你现在正在做的是在你的D类构造函数中创建一个B()的实例,它没有被使用:
D(int ii) { B(ii); /* <- useless*/ }
D(int ii) { B(ii); cout << "Constructor for Dn"; }
调用B
的默认构造函数。B(ii)
创建了一个B
的临时对象,一旦D
的构造函数返回,该对象就会被销毁。简而言之,它不调用正在构建的对象基类的构造函数。
解决方案:
若要能够调用基类的特定构造函数,应使用成员初始化器列表。
D(int ii) : B(ii)
{
}
此代码:
class C:public B
{
C() { cout << "Constructor for Cn"; }
};
尝试调用B
的默认构造函数。
你可能想要:
class C:public B
{
C() : B(0) { cout << "Constructor for Cn"; }
};
但这取决于你的逻辑。
以下也是错误的:
D(int ii) { B(ii); cout << "Constructor for Dn"; }
应该是
D(int ii) : B(ii) { cout << "Constructor for Dn"; }
在子类构造函数的主体中调用基类构造函数只会创建一个不做任何事情的临时对象。若要获得所需的行为,必须调用初始值设定项列表中的构造函数。
您正在创建一个从B派生的D,但D的ctor没有将参数传递给B的构造函数,这需要B有一个默认的ctor。
为了解决这个问题,您通常需要编写D来为B的ctor:提供一个参数
class D : public B {
C C;
public:
D(int ii) : B(ii) { cout << "ctor for Dn"; }
};
您需要意识到,在进入构造函数的主体时,基本子对象和成员子对象已经构造好了!也就是说,如果你有一个没有默认值的基或成员,你需要在成员初始值设定项列表中传递它的参数:
D(int ii): B(ii) { std::cout << "constructor for Dn"; }
您在D
构造函数的主体中构建的对象只是一个临时对象,在您的情况下并没有真正起到任何作用(不过,在某些情况下,临时对象可能很有用)。
相关文章:
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 初始化具有非默认构造函数的std::数组项的更好方法
- 具有默认模板类型的默认构造函数的类型推导
- 如何使用非默认构造函数实例化模板化类
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 声明没有默认构造函数的字段
- 没有默认构造函数作为模板参数的自定义比较器
- C++17 没有默认构造函数的地图放置(私有默认构造函数)
- 使用移动调用对等构造函数unique_ptr默认构造函数
- C++复制构造函数和默认构造函数
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 为什么即使我调用参数化构造函数也会调用默认构造函数?
- 具有非默认构造函数的单例类
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?
- 在C++中使用默认构造函数初始化对象的不同方法
- 在没有默认构造函数的情况下创建的派生对象
- 强制使用默认构造函数对成员进行未初始化的声明
- 使用默认构造函数初始化对象的不同方法
- 创建类类型的动态分配数组,其中类不得具有默认构造函数