这是代码:
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;}
这些是错误:
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
我不明白以下内容:
- 为什么
twoCats
的构造函数会尝试调用 cat
的默认构造函数?当然,它不需要构造 cat
的实例,因为当 twoCats
被初始化时,它将传递一个已经初始化的 cat
实例,该实例将具有是否传递了 int height
参数?
- 为什么同一 block 错误消息显示两次?我在 Ubuntu 12.04 上调用了
g++ main.cpp
。
您需要一个默认构造函数或在 twoCats
构造函数初始化列表中显式初始化 cat 对象以避免默认构造。
Why does the constructor for twoCats try to call the default
constructor for cat? Surely it does not need to construct an instance
of cat as when twoCats is initialised it will be passed an already
initialised instance of cat which will have been passed the int height
argument?
需要为cat
对象构造默认值
private:
cat firstCat;
cat secondCat;
在 twoCats
类中,因为您没有初始化它们。在你的构造函数中
cat::cat (int inputHeight)
{
height = inputHeight;
^^^^^^^^^^^^^^^^^^^^
} // this is assignment
这是对已创建对象的赋值。
规则如下:如果你没有在ctor
初始化列表中显式初始化实例,那么
- 调用默认的
ctor
- 您最终分配给
ctor
主体中已经默认构造的对象。
因此,如果您不在初始化列表中进行初始化,您将面临额外调用的惩罚。
C++ 标准 n3337 § 12.6.2/10 初始化基和成员
In a non-delegating constructor, initialization proceeds in the
following order:
— First, and only for the constructor of the most derived class (1.8),
virtual base classes are initialized in the order they appear on a
depth-first left-to-right traversal of the directed acyclic graph of
base classes, where “left-to-right” is the order of appearance of the
base classes in the derived class base-specifier-list.
— Then, direct base classes are initialized in declaration order as
they appear in the base-specifier-list (regardless of the order of the
mem-initializers).
— Then, non-static data members are initialized in the order they were
declared in the class definition (again regardless of the order of the
mem-initializers).
— Finally, the compound-statement of the constructor body is executed.
[ Note: The declaration order is mandated to ensure that base and
member subobjects are destroyed in the reverse order of
initialization. — end note ]
Here is a code demo.