编译器看不到参数



我是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()构造函数。

阅读更多:了解C++中的初始化列表

使用指针

你真的希望你的Sword只属于你的Hero吗?你的Hero可能会掉一个Sword,另一个Hero会捡起来吗?

在这种情况下,你可能不希望你的Hero有一个Sword作为成员——相反,你希望有一个指针指向他当前持有的Sword——例如,如果他没有持有剑,那么可能是nullptr

您的Sword类没有不带参数的构造函数。在Hero()的开头(在打开{之前),初始值设定项列表中未指定的成员将获得默认构造。

试试这个:

Hero() : magic_sword(2) {
};

或者,您可以向Sword添加另一个不带参数的构造函数。

Sword(){
lenght = -1;
};

(让我猜一下——你来自Java?)

编译器正确。Sword没有默认构造函数,这是一个问题。

此时代码中,

public:
Hero(){
// This point.

C++要求CCD_ 28已经被构造。与Java不同,没有"null"值作为默认值。到那时构造Sword的唯一方法是使用无参数构造函数,而Sword没有无参数构造函数。

当然,有一种方法可以使代码正常工作。语法如下:

public:
Hero() : magic_sword(2) {
}

这告诉编译器如何在Hero的构造函数主体开始之前调用Sword的构造函数。

请注意您的设计:您可能需要magic_sword作为某种指针(原始、唯一或引用计数)。与Java不同,编写的magic_sword不是对Sword实例的引用,而是一个实际实例,完全包含在Hero实例中。

最新更新