我有多个继承的类,但发生错误C2<int (__cdecl *)(int)>': no appropriate default constructor available
,但是我为C1,C2
定义了参数化构造函数。
一个相关的问题是,我在某些代码中看到标有???
的注释行。是什么意思-它正在初始化C2
中C3
的默认构造函数?
#include <iostream>
int y(int)
{ int a=1; return a }
template<typename F>
class C1
{
public:
F f1;
C1(F g) : f1(g) {}
};
template<typename F>
class C2 : public C1<F>
{
public:
F f2;
C2(F g) : f2(g) {}
};
template<typename F>
class C3 : public C2<F>
{
public:
F f3;
C3(F g) : f3(g) {}
//C3 (F g) : C2<F>(g) {} ???
};
int main()
{
C1 o1(y);
C2 o2(y);
C3 o3(y);
}
答案 0 :(得分:2)
在构造作为另一个类的子类的类时,将调用父级的默认构造函数(除非像标记为???
的行那样显式调用另一个构造函数)。但是,看到为每个类都提供了构造函数时,编译器并未生成隐式默认构造函数。因此,当您创建C2
的实例时,编译器尝试调用缺少的C1
的默认构造函数时,找不到它。
如果您确实提供了默认的构造函数,则可以这样做:
#include <iostream>
int y(int) {
int a=1;
return a;
}
template<typename F>
class C1 {
public:
F f1{};
C1() = default;
C1(F g)
: f1(g)
{ }
};
template<typename F>
class C2 : public C1<F>
{
public:
F f2{};
C2() = default;
C2(F g)
: f2(g)
{ }
};
template<typename F>
class C3 : public C2<F>
{
public:
F f3{};
C3() = default;
C3(F g)
: f3(g)
{ }
//C3 (F g) : C2<F>(g) {} ???
};
int main()
{
C1 o1(y);
C2 o2(y);
C3 o3(y);
}
标记为???
的行调用特定的父构造函数,而不是依赖对父类的默认构造函数的隐式调用。
因此,您可以提供如上所述的默认构造函数,也可以采用???
行语法来调用特定的构造函数-这取决于您的类设计和意图。
答案 1 :(得分:1)
正如Sam所说,C2
的构造函数正在尝试为C1
调用默认的构造函数,该默认构造函数不存在。同样,C3
试图调用C2
的默认构造函数。
有两个修复程序:
为C1
和C2
定义默认构造函数,或者:
修改C2
的构造函数以调用确实存在的构造函数,如下所示:
C2(F g) : C1 <F> (g), f2(g) {}
以及类似的C3
的构造函数,如下所示:
C3(F g) : C2 <F> (g), f3(g) {}
我想,这本身就能回答您的第二个问题。
答案 2 :(得分:0)
C2<F>(g)
通过调用基类的构造函数来初始化基类。如果您自己不调用构造函数,则编译器将尝试为基类(C2<F>::C2()
)调用默认构造函数。您的所有类都没有默认构造函数,这是错误的根源。但是实际上您应该做的是自己调用基类的构造函数。
C2(F g) : C1<F>(g), f2(g) {}
C3(F g) : C2<F>(g), f3(g) {}