c ++派生类的默认构造函数

时间:2014-01-22 02:46:46

标签: c++ inheritance compiler-construction constructor

如果我们编译了下面的代码,编译会抱怨“没有匹配的函数来调用'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默认构造函数不会导致编译错误。

5 个答案:

答案 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()构造函数被删除并再次编译,为什么它不会引发错误,因为按照概念,如果没有用户定义,编译器会自动创建一个默认构造函数。

  • 答案是,为了避免出现“没有匹配的函数要调用”的错误,编译器会隐式删除派生类apple()的构造函数。 您可以通过不定义派生类的默认构造函数,然后在主函数中创建派生类的对象来证明这一点。它将引发如下错误:

在函数'int main()'中:

错误:使用已删除的功能'apple :: apple()'

注意:“ apple :: apple()”被隐式删除,因为默认定义格式不正确