我是C++的新手,想玩转类。
我的密码
在我的世界中,有英雄和剑。英雄们持剑。这不应该太难。
// Defining swords
class Sword
{
// The most important thing about a sword is its length.
int lenght;
public:
// only constructor and destructor
Sword(int swordlength){
lenght = swordlength;
};
~Sword(){};
};
// defining heros (as people with magic swords)
class Hero
{
Sword magic_sword;
public:
// each hero gets a standard sword
Hero(){
int meters = 2;
magic_sword = Sword(meters);
};
~Hero(){};
};
int main(){
return 0;
}
编译器对此有何看法
当我编译此代码(
g++ hero.cpp
)时,出现错误: In constructor 'Hero::Hero()':
20:9: error: no matching function for call to 'Sword::Sword()'
20:9: note: candidates are:
8:3: note: Sword::Sword(int)
8:3: note: candidate expects 1 argument, 0 provided
2:7: note: constexpr Sword::Sword(const Sword&)
2:7: note: candidate expects 1 argument, 0 provided
我认为问题是
使用
clang++
编译代码也将失败,但是错误消息并不那么明确,因此我不会在此处发布。似乎调用构造函数
Sword(meters)
失败,因为我提供了0而不是1参数。但是我显然给了它一个参数(meters
),所以我想我在这里误解了一些东西。我的错误是什么,我该怎么办?
最佳答案
您的Hero
始终具有Sword
。
这意味着在实例化该类的那一刻,在Hero::Hero
构造函数开始运行之前,它已经必须具有“默认” Sword
。编译器提示它不知道如何制作这样的“默认” Sword
。
现在,您可以通过多种方式解决此问题:
使用初始化列表
在构造函数的定义中,您可以指定如何初始化对象的成员(在实际构造函数运行之前)。这不同于在构造函数的主体中为其分配新值(在您的示例中发生)。为此,请在构造函数的签名后指定一个冒号(:
),然后在成员字段初始化程序中指定它,如下所示:
Hero() : magic_sword(2)
{
// do other stuff to set up your hero
}
这将导致立即使用
magic_sword
构造函数初始化Sword::Sword(int)
,这意味着您不需要默认的Sword::Sword()
构造函数。阅读更多:Understanding Initialization Lists in C++
使用指针
您是否真的希望
Sword
完全属于Hero
?您的Hero
是否可以删除Sword
,而另一个Hero
可以接收它呢?在这种情况下,您可能不希望
Hero
成为成员的Sword
-相反,您想要一个指向他当前持有的Sword
的指针-如果他不持有,则可能是nullptr
一把剑!