在构造函数中,候选者需要1个参数,0提供

tex*_*ood 7 c++ compiler-errors g++

这是代码:

class cat
{
    private:
        int height;
    public:
        cat (int inputHeight);
};

cat::cat (int inputHeight)
{
    height = inputHeight;
}

class twoCats
{
    private:
        cat firstCat;
        cat secondCat;
    public:
        twoCats (cat theFirstCat);
        void addSecondCat (cat theSecondCat);
};

twoCats::twoCats (cat theFirstCat)
{
    firstCat = theFirstCat;
}

void twoCats::addSecondCat (cat theSecondCat)
{
    secondCat = theSecondCat;
}

int main() {return 0;}
Run Code Online (Sandbox Code Playgroud)

这些是错误:

main.cpp: In constructor ‘twoCats::twoCats(cat)’:
main.cpp:24:34: error: no matching function for call to ‘cat::cat()’
main.cpp:24:34: note: candidates are:
main.cpp:9:1: note: cat::cat(int)
main.cpp:9:1: note:   candidate expects 1 argument, 0 provided
main.cpp:1:7: note: cat::cat(const cat&)
main.cpp:1:7: note:   candidate expects 1 argument, 0 provided
main.cpp:24:34: error: no matching function for call to ‘cat::cat()’
main.cpp:24:34: note: candidates are:
main.cpp:9:1: note: cat::cat(int)
main.cpp:9:1: note:   candidate expects 1 argument, 0 provided
main.cpp:1:7: note: cat::cat(const cat&)
main.cpp:1:7: note:   candidate expects 1 argument, 0 provided
Run Code Online (Sandbox Code Playgroud)

我不明白以下几点:

  1. 为什么构造函数twoCats尝试调用默认构造函数cat?当然,它不需要构造一个实例,cat因为twoCats初始化时它将被传递一个已经初始化的实例,cat该实例将被传递int height参数?
  2. 为什么同一块错误消息显示两次?我打电话g++ main.cpp给Ubuntu 12.04.

4pi*_*ie0 6

您需要一个默认构造函数或在twoCats构造函数初始化列表中显式初始化cat对象,以避免默认构造。

为什么twoCats的构造函数尝试调用cat的默认构造函数?当然,它不需要构造cat的实例,因为在初始化twoCats时,它将传递一个已经初始化的cat实例,而该实例将已经通过int height参数传递了?

它需要为cat对象构造默认值

private:
    cat firstCat;
    cat secondCat;
Run Code Online (Sandbox Code Playgroud)

在课堂上,twoCats因为您没有初始化它们。在您的构造函数中

cat::cat (int inputHeight)
{
    height = inputHeight;
    ^^^^^^^^^^^^^^^^^^^^
}   // this is assignment
Run Code Online (Sandbox Code Playgroud)

这是分配给已经创建的对象。

规则如下:如果未在ctor初始化列表中显式初始化实例,则

  1. 默认ctor称为
  2. 最终,您将分配给ctor主体中已经默认构造的对象。

因此,如果您未在初始化列表中进行初始化,则将面临额外呼叫的惩罚。

C ++标准n3337 § 12.6.2 / 10初始化碱和构件

在非委托构造函数中,初始化按以下顺序进行:

—首先,并且仅对于大多数派生类(1.8)的构造函数而言,虚拟基类按照它们在基类有向无环图的深度优先从左到右遍历时出现的顺序进行初始化,其中“左“从右到右”是基类在派生类base-specifier-list中的出现顺序。

—然后,直接基类按照它们出现在base-specifier-list中的声明顺序进行初始化(与mem-initializers的顺序无关)。

然后,初始化非静态数据成员按照它们在类定义中声明的顺序(同样,无论mem-initializer的顺序如何)。

最后,执行构造函数主体的复合语句

[注意:声明顺序是强制执行的,以确保以相反的初始化顺序销毁基础和成员子对象。—尾注]

这是一个代码演示。