编译器无法看到参数

时间:2017-11-10 13:30:02

标签: c++ class constructor

我是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),所以我想我在这里误解了一些东西。

我的错误是什么?我该怎么办?

3 个答案:

答案 0 :(得分:7)

您的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可以选择它吗?

在这种情况下,您可能不希望HeroSword作为成员 - 相反,您需要指针到{{ 1}}他目前正在持有 - 如果他是,例如,他没有握剑,那么可能是Sword

答案 1 :(得分:3)

您的Sword类没有没有参数的构造函数。在Hero()开始时(在开始{之前),initializer list中未指定的成员将默认构建。

试试这个:

Hero() : magic_sword(2) {
};

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

Sword(){
    lenght = -1;
};

答案 2 :(得分:1)

(我猜 - 你来自Java?)

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

到目前为止,在代码中,

public:
  Hero(){
    // This point.

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

当然,有一种方法可以使代码工作。这是语法:

public:
  Hero() : magic_sword(2) {

  }

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

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