如果我们编译了下面的代码,编译会抱怨“没有匹配的函数来调用'fruit :: fruit()'”
我认为原因是: apple构造函数调用默认的水果构造函数,它找不到一个
但如果我删除了apple构造函数(从LineA注释到LineB)并再次编译。它编译没有错误。为什么? 如果我们没有为apple类定义任何构造函数,请从book中。编译器将创建一个。为什么编译器创建的apple默认构造函数不会抱怨缺少fruit :: fruit()。 感谢
class fruit
{
public:
int seed;
//fruit()
//{
// cout <<"fruit" <<endl;
// seed = 12;
//}
fruit(int i)
{
cout <<i<<"fruit"<<endl;
}
virtual void plant()
{
cout << "fruit" <<endl;
}
};
class apple:public fruit
{
public:
apple() //lineA
{
//cout << "apple" << endl;
} //lineB
void plant()
{
cout << "apple" << endl;
}
};
int main(){}
谢谢
我知道如何使这段代码有效。我的问题是为什么删除apple默认构造函数不会导致编译错误。
答案 0 :(得分:1)
[C ++ 11标准。]
12.1.5。如果类X没有用户声明的构造函数,则没有参数的构造函数被隐式声明为默认值(8.4)。
12..1 ......“如果使用的话,实施将隐含地定义它们”......
因此,如果删除apple::apple()
,除非实际调用apple::apple()
,否则实现可能不会创建fruit::fruit()
,因此无需引用apple::apple()
。
如上所述,代码不会调用{{1}}。
答案 1 :(得分:0)
你需要拥有水果的默认构造函数或者从apple设置一个id。所以要么
fruit::fruit() {}
或
apple::apple() : fruit(1) {}
如果我们没有为apple类定义任何构造函数,请从书中获取。该 编译器将创建一个。为什么编译器创建的构造函数 不抱怨失水果()
因为您已显式声明了构造函数。
答案 2 :(得分:0)
我认为你需要的是一个初始化列表。您需要明确调用
class apple:public fruit
{
public:
apple() : fruit(10)
{
//cout << "apple" << endl;
}
void plant()
{
cout << "apple" << endl;
}
};
有关详细信息,请参阅http://www.cprogramming.com/tutorial/initialization-lists-c++.html。
答案 3 :(得分:0)
如果明确定义构造函数,则覆盖默认构造函数。在这种情况下,您在fruit类中定义了一个参数。现在,当您创建类apple的对象时,继承的行为方式如下: 1.调用基类的构造函数(fruit class)。在这种情况下,它将调用基类的默认构造函数,因为您没有使用一个fruit参数显式调用构造函数 2.执行派生类的构造函数,即apple类
编译器将无法找到基类的默认构造函数(在步骤1中),因此出现此错误。解决方案是在apple类中调用带有一个参数的fruit类的构造函数,或者定义一个没有参数的构造函数,或者删除两者,以满足您的需要。
如果您需要有关代码或更多解释的帮助,请告诉我们(代码不包含在您将尝试理解OOP概念的意图中)。
答案 4 :(得分:0)
第一件事是,编译器需要插入代码来调用基类的默认构造函数,因此,它需要基类的默认构造函数,否则会引发错误:“没有匹配的调用函数”。
现在要问的一个问题是,如果apple()构造函数被删除并再次编译,为什么它不会引发错误,因为按照概念,如果没有用户定义,编译器会自动创建一个默认构造函数。
在函数'int main()'中:
错误:使用已删除的功能'apple :: apple()'
注意:“ apple :: apple()”被隐式删除,因为默认定义格式不正确