简体   繁体   English

C ++没有匹配函数来调用错误

[英]C++ no matching function for call to error

I am trying to simulate a certain game as an exercise (dont ask me which, you will know if you know the game), however, I just learnt objects and class on the internet and the whole thing is still so confusing to me. 我正在尝试模拟某种游戏作为练习(不要问我,哪一个,如果您知道游戏,您会知道),但是,我只是在互联网上学习了对象和类,整个事情仍然让我感到困惑。 The following is a section of my code that is giving me an error. 以下是我的代码的一部分,给了我一个错误。

The error I have is: 我的错误是:

C:\Users\N\Desktop\Untitled1.cpp    In constructor 'ekop::Moveset::Moveset()':
56  9   C:\Users\N\Desktop\Untitled1.cpp    [Error] no matching function for call to 'Move::Move()'
56  9   C:\Users\N\Desktop\Untitled1.cpp    [Note] candidates are:
14  3   C:\Users\N\Desktop\Untitled1.cpp    [Note] Move::Move(std::string, int, int, int)
14  3   C:\Users\N\Desktop\Untitled1.cpp    [Note] candidate expects 4 arguments, 0 provided
11  7   C:\Users\N\Desktop\Untitled1.cpp    [Note] Move::Move(const Move&)
11  7   C:\Users\N\Desktop\Untitled1.cpp    [Note] candidate expects 1 argument, 0 provided
56  9   C:\Users\N\Desktop\Untitled1.cpp    [Error] no matching function for call to 'Move::Move()'
56  9   C:\Users\N\Desktop\Untitled1.cpp    [Note] candidates are:
14  3   C:\Users\N\Desktop\Untitled1.cpp    [Note] Move::Move(std::string, int, int, int)
14  3   C:\Users\N\Desktop\Untitled1.cpp    [Note] candidate expects 4 arguments, 0 provided
11  7   C:\Users\N\Desktop\Untitled1.cpp    [Note] Move::Move(const Move&)
11  7   C:\Users\N\Desktop\Untitled1.cpp    [Note] candidate expects 1 argument, 0 provided
56  9   C:\Users\N\Desktop\Untitled1.cpp    [Error] no matching function for call to 'Move::Move()'
56  9   C:\Users\N\Desktop\Untitled1.cpp    [Note] candidates are:
14  3   C:\Users\N\Desktop\Untitled1.cpp    [Note] Move::Move(std::string, int, int, int)
14  3   C:\Users\N\Desktop\Untitled1.cpp    [Note] candidate expects 4 arguments, 0 provided
11  7   C:\Users\N\Desktop\Untitled1.cpp    [Note] Move::Move(const Move&)
11  7   C:\Users\N\Desktop\Untitled1.cpp    [Note] candidate expects 1 argument, 0 provided
56  9   C:\Users\N\Desktop\Untitled1.cpp    [Error] no matching function for call to 'Move::Move()'
56  9   C:\Users\N\Desktop\Untitled1.cpp    [Note] candidates are:
14  3   C:\Users\N\Desktop\Untitled1.cpp    [Note] Move::Move(std::string, int, int, int)
14  3   C:\Users\N\Desktop\Untitled1.cpp    [Note] candidate expects 4 arguments, 0 provided
11  7   C:\Users\N\Desktop\Untitled1.cpp    [Note] Move::Move(const Move&)
11  7   C:\Users\N\Desktop\Untitled1.cpp    [Note] candidate expects 1 argument, 0 provided
C:\Users\N\Desktop\Untitled1.cpp    In constructor 'ekop::ekop()':
52  12  C:\Users\N\Desktop\Untitled1.cpp    [Note] synthesized method 'ekop::Moveset::Moveset()' first required here

I don't know what went wrong, the code is below. 我不知道出了什么问题,代码在下面。 Don't tell me not to use using namespace std; 不要告诉我不要using namespace std; , I know I am not supposed to do that but I am not going to fix that in this program. ,我知道我不应该这样做,但是我不会在此程序中修复该问题。

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
#include <string>
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
using namespace std;

class Move
{
    public:
        Move(string a, int b, int c, int d)
        {
            name = a;
            type_num = b;
            power = c;
            accuracy = d;
        }

        void setName (string a)
        {
            name = a;
        }

        void setType_num(int a)
        {
            type_num = a;
        }

        void setPower(int a)
        {
            power = a;
        }

        void setAccuracy(int a)
        {
            accuracy = a;
        }

    private:
        string name, type;
        int type_num, power, accuracy;
};

class ekop
{
    public:
        ekop()
        {
            Moveset moveset;
        }

    private:
        class Moveset
        {
            public:
                //constructor
                //retrievors
            private:
                Move slot1, slot2, slot3, slot4;
        };
};

int main()
{
    //lines of code
    return EXIT_SUCCESS;
}

edit 1: I had this constructor for the class Moveset, but since it didnt affect the error when I took it out, so I didnt include that in the post just now. 编辑1:我为Moveset类提供了此构造函数,但由于在取出错误时它不会影响错误,因此我现在并未在帖子中包括该错误。

Moveset()
                {
                    slot1.setName("MOVE 1");
                    slot1.setType_num(rand()%18);
                    slot1.setPower(10*(rand%15+1));
                    slot1.setAccuracy(5*(rand%11+10));
                    //repeat for the rest of the slots
                }

edit 2: Now if I do this instead: 编辑2:现在,如果我改为这样做:

        //No change before this
        class Moveset
        {
            public:
                //constructor
                //retrievors
            private:
                Move slot1("MOVE 1", rand() % 18, 10*(rand % 15 + 1), 5 * (rand % 11 + 10)),
                     slot2("MOVE 2", rand() % 18, 10*(rand % 15 + 1), 5 * (rand % 11 + 10)), 
                     slot3("MOVE 3", rand() % 18, 10*(rand % 15 + 1), 5 * (rand % 11 + 10)),
                     slot4("MOVE 4", rand() % 18, 10*(rand % 15 + 1), 5 * (rand % 11 + 10));
        };
};

//no change after this

I get this error instead: 我得到这个错误:

62  16  C:\Users\N\Desktop\Untitled1.cpp    [Error] expected identifier before string constant
62  16  C:\Users\N\Desktop\Untitled1.cpp    [Error] expected ',' or '...' before string constant
63  16  C:\Users\N\Desktop\Untitled1.cpp    [Error] expected identifier before string constant
63  16  C:\Users\N\Desktop\Untitled1.cpp    [Error] expected ',' or '...' before string constant
64  13  C:\Users\N\Desktop\Untitled1.cpp    [Error] expected identifier before string constant
64  13  C:\Users\N\Desktop\Untitled1.cpp    [Error] expected ',' or '...' before string constant
65  13  C:\Users\N\Desktop\Untitled1.cpp    [Error] expected identifier before string constant
65  13  C:\Users\N\Desktop\Untitled1.cpp    [Error] expected ',' or '...' before string constant

A MoveSet contains four default-initialized Move instances, but Move has no default constructor – because you have defined a constructor, which suppresses automatic generation of a default constructor. MoveSet包含四个默认初始化的Move实例,但是Move没有默认的构造函数–因为您已定义了一个构造函数,该构造函数禁止自动生成默认构造函数。

Since the class needs a user-defined default constructor (built in type data members will otherwise have arbitrary values), define one. 由于该类需要用户定义的默认构造函数(否则,内置类型数据成员将具有任意值),因此请定义一个。

One way to define it is to provide default values for all arguments of the existing constructor, but I'd define a separate default constructor. 定义它的一种方法是为现有构造函数的所有参数提供默认值,但我将定义一个单独的默认构造函数。


In passing, the existing code 顺便说一句,现有代码

Move(string a, int b, int c, int d)
{
    name = a;
    type_num = b;
    power = c;
    accuracy = d;
}

… which uses assignments to initialize members, has a problem as a general way to do this. …使用赋值来初始化成员,这是一个普遍的问题。 Namely, that members of class type that can't be default-initialized, can't be initialized this way. 即,无法通过默认方式初始化的类类型的成员无法初始化。 You'd experience the same problem as above, namely error messages about lacking a default constructor. 您将遇到与上述相同的问题,即有关缺少默认构造函数的错误消息。

A solution is to use a member initializer list , like this: 一种解决方案是使用成员初始化器列表 ,如下所示:

Move( string a, int b, int c, int d )
    : name( a ), type_num( b ), power( c ), accuracy( d )
{}

There are further possible refinements, such as move for efficiency or const for clarity (unfortunately one has to choose between them), but the important thing is to just generally adopt this convention of using member initializer lists, which works much more generally than assignments to members. 还有其他可能的改进,例如为提高效率而move或为清楚起见使用const (不幸的是,必须在它们之间进行选择),但重要的是通常只采用这种使用成员初始化器列表的约定,该约定的作用远比分配给成员。

Basically, you've got no default constructor for Move. 基本上,您没有Move的默认构造函数 To make this code work, add the following to the public section of the Move class: 要使此代码正常工作,请将以下内容添加到Move类的public部分:

Move() {
    //Give fields default values here
}

When you declare a variable without initializing it, it calls the default constructor (the constructor with no arguments) to give the variable default values until it's used. 当您声明变量而未对其进行初始化时,它将调用默认构造函数(不带参数的构造函数)以提供变量默认值,直到使用它为止。 Sometimes these default values are kept, sometimes you assign a new object to it.. But that's depends on what you want to do and isn't really relevant. 有时会保留这些默认值,有时会为它分配一个新对象。但这取决于您要执行的操作,并且并不真正相关。

Edit: Okay so to elaborate, there are a couple of ways to declare/initialize variables in C++. 编辑:好了,详细说明一下,有两种方法可以在C ++中声明/初始化变量。 I'll use std::string as an example, but this applies to any type (even the fundamental types, though their classes aren't defined, per se, as much as just built into the language): 我将以std :: string为例,但这适用于任何类型(甚至是基本类型,尽管它们的类本身并没有定义,就像语言中内置的一样):

std::string str1;
std::string str2 = "Two";
std::string str3("Three");
std::string str4 = std::string("Four");

str1 is just a declaration, the rest are declarations and initializations (they declare the variable, and then give it an initial value). str1只是一个声明,其余的是声明初始化(它们先声明变量,然后为其赋一个初始值)。

str1 calls the default constructor, because no initial value is provided. str1调用默认构造函数,因为没有提供初始值。 Therefore, the compiler needs something to assign to str1 and the default constructor provides that something. 因此,编译器需要一些东西来分配给str1 ,并且默认构造函数提供了一些东西。

str2 and str3 are actually different styles of the exact same call - a call to one of the parameterized std::string constructors (namely, in this case, the std::string(const char*) constructor). str2str3实际上是完全相同的调用的不同样式-调用参数化的std::string构造函数之一(即,在本例中为std::string(const char*)构造函数)。 str3 is fairly self explanatory: its like a normal function call, only it's the constructor being called, not a normal function. str3str3说明:它像普通函数调用一样,只是被调用的构造函数,而不是普通函数。 str2 shows a funny thing about C++ - when initializing a variable with the = sign, it calls a constructor. str2显示了有关C ++的一个有趣的事情-用=符号初始化变量时,它将调用构造函数。 In this case, is calls a converting constructor , which I'll go into a little more detail about, but I'll wait till the end. 在这种情况下,is调用了一个转换构造函数 ,我将对其进行详细介绍,但是我将等到最后。

Finally, str4 , unlike the others, actually calls two constructors (making it the least efficient, technically speaking). 最后, str4与其他str4不同,实际上调用了两个构造函数(从技术上来说,效率最低)。 The first one called is the std::string("Four") , which creates an unnamed std::string object, which is then passed to the std::string copy constructor (which looks like std::string(std::string&) ) to create the str4 variable. 第一个调用的是std::string("Four") ,它将创建一个未命名的std::string对象, 然后将该对象传递给std::string 复制构造函数 (看起来像std::string(std::string&) )创建str4变量。

It goes like this: an unnamed std::string object is created and given the value "Four" ( std::string("Four") ). 就像这样:创建了一个未命名的std::string对象,并为其赋予了值“ Four”( std::string("Four") )。 That object is then passed (by that quirky = sign again) to the std::string copy constructor, to copy the unnamed string object to str4 , completing it's creation. 然后将该对象(再次通过该古怪的=符号)传递给std::string复制构造函数,以将未命名的字符串对象复制到str4 ,从而完成创建。 See that this method calls two constructors, creating an extra unnecessary object that's used in the creation of str4 . 看到此方法调用了两个构造函数,创建了一个多余的对象,该对象在创建str4

Now - converting constructors . 现在转换的构造函数 If a class defines a constructor that takes a single parameter, that constructor is a converting constructor. 如果一个类定义了一个采用单个参数的构造函数,则该构造函数是一个转换构造函数。 So basically, whenever an object of that class is initialized with a value that can be taken by a converting constructor, that value is passed to the constructor and the constructor handles it from there. 因此,基本上,只要该类的对象初始化为转换构造函数可以采用的值,该值就会传递给构造函数,然后构造函数从那里处理该值。

Converting constructors aren't anything special - they're just normal constructors. 转换构造函数没有什么特别的-它们只是普通的构造函数。 The only difference is that you don't need parentheses to call it when initializing, you just put the value there. 唯一的区别是,初始化时不需要括号即可调用,只需将值放在此处即可。 Take the std::string(const char*) constructor. 采用std::string(const char*)构造函数。 This constructor acts to convert const char* (known as a C-style string, from the days of the C language) to a std::string object. 此构造函数用于将const char* (从C语言时代开始,称为C样式字符串)转换为std::string对象。 With a converting constructor, you can put the parameter value (eg const char*) anywhere that a std::string is required (in the return value of a function, for example) and it will automatically create a std::string object from the const char* (in case you didn't know, whenever you type something like "Hello World" it is actually a const char* value, though is it often converted to a std::string by your code). 使用转换构造函数,您可以将参数值(例如const char *)放在需要std::string任何位置(例如,在函数的返回值中),它将自动从以下位置创建std::string对象const char* (如果您不知道,每当您键入"Hello World"它实际上都是const char*值,尽管它通常通过您的代码转换为std::string )。

One way you can avoid creating a converting constructor while still having one argument (because automatic - aka implicit - conversions can sometimes be annoying) is to put the keyword explicit in front of the constructor declaration, which will tell the compilation not to do implicit conversions - meaning that whenever you want to convert, you must use std::string("Hello World") rather than just "Hello World" . 您可以避免在仍然有一个参数的情况下创建转换构造函数的一种方法(因为自动-aka隐式-转换有时可能很烦人)是将关键字explicit放在构造函数声明的前面,这将告诉编译器不要进行隐式转换-表示无论何时要转换,都必须使用std::string("Hello World")而不是仅使用"Hello World"

Hopefully you understand that I'm talking about, if not just let me know! 希望您能理解我的意思,即使不让我知道! By the way, I still need to verify what I've said about that = sign, which I'll use the Visual Studio debugger to do when I get home. 顺便说一句,我仍然需要验证我对=符号的看法,回到家时,我将使用Visual Studio调试器进行此操作。 I will update the post to reflect my findings. 我将更新帖子以反映我的发现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM