繁体   English   中英

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

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

我正在尝试模拟某种游戏作为练习(不要问我,哪一个,如果您知道游戏,您会知道),但是,我只是在互联网上学习了对象和类,整个事情仍然让我感到困惑。 以下是我的代码的一部分,给了我一个错误。

我的错误是:

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

我不知道出了什么问题,代码在下面。 不要告诉我不要using namespace std; ,我知道我不应该这样做,但是我不会在此程序中修复该问题。

#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;
}

编辑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
                }

编辑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

我得到这个错误:

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

MoveSet包含四个默认初始化的Move实例,但是Move没有默认的构造函数–因为您已定义了一个构造函数,该构造函数禁止自动生成默认构造函数。

由于该类需要用户定义的默认构造函数(否则,内置类型数据成员将具有任意值),因此请定义一个。

定义它的一种方法是为现有构造函数的所有参数提供默认值,但我将定义一个单独的默认构造函数。


顺便说一句,现有代码

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

…使用赋值来初始化成员,这是一个普遍的问题。 即,无法通过默认方式初始化的类类型的成员无法初始化。 您将遇到与上述相同的问题,即有关缺少默认构造函数的错误消息。

一种解决方案是使用成员初始化器列表 ,如下所示:

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

还有其他可能的改进,例如为提高效率而move或为清楚起见使用const (不幸的是,必须在它们之间进行选择),但重要的是通常只采用这种使用成员初始化器列表的约定,该约定的作用远比分配给成员。

基本上,您没有Move的默认构造函数 要使此代码正常工作,请将以下内容添加到Move类的public部分:

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

当您声明变量而未对其进行初始化时,它将调用默认构造函数(不带参数的构造函数)以提供变量默认值,直到使用它为止。 有时会保留这些默认值,有时会为它分配一个新对象。但这取决于您要执行的操作,并且并不真正相关。

编辑:好了,详细说明一下,有两种方法可以在C ++中声明/初始化变量。 我将以std :: string为例,但这适用于任何类型(甚至是基本类型,尽管它们的类本身并没有定义,就像语言中内置的一样):

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

str1只是一个声明,其余的是声明初始化(它们先声明变量,然后为其赋一个初始值)。

str1调用默认构造函数,因为没有提供初始值。 因此,编译器需要一些东西来分配给str1 ,并且默认构造函数提供了一些东西。

str2str3实际上是完全相同的调用的不同样式-调用参数化的std::string构造函数之一(即,在本例中为std::string(const char*)构造函数)。 str3str3说明:它像普通函数调用一样,只是被调用的构造函数,而不是普通函数。 str2显示了有关C ++的一个有趣的事情-用=符号初始化变量时,它将调用构造函数。 在这种情况下,is调用了一个转换构造函数 ,我将对其进行详细介绍,但是我将等到最后。

最后, str4与其他str4不同,实际上调用了两个构造函数(从技术上来说,效率最低)。 第一个调用的是std::string("Four") ,它将创建一个未命名的std::string对象, 然后将该对象传递给std::string 复制构造函数 (看起来像std::string(std::string&) )创建str4变量。

就像这样:创建了一个未命名的std::string对象,并为其赋予了值“ Four”( std::string("Four") )。 然后将该对象(再次通过该古怪的=符号)传递给std::string复制构造函数,以将未命名的字符串对象复制到str4 ,从而完成创建。 看到此方法调用了两个构造函数,创建了一个多余的对象,该对象在创建str4

现在转换的构造函数 如果一个类定义了一个采用单个参数的构造函数,则该构造函数是一个转换构造函数。 因此,基本上,只要该类的对象初始化为转换构造函数可以采用的值,该值就会传递给构造函数,然后构造函数从那里处理该值。

转换构造函数没有什么特别的-它们只是普通的构造函数。 唯一的区别是,初始化时不需要括号即可调用,只需将值放在此处即可。 采用std::string(const char*)构造函数。 此构造函数用于将const char* (从C语言时代开始,称为C样式字符串)转换为std::string对象。 使用转换构造函数,您可以将参数值(例如const char *)放在需要std::string任何位置(例如,在函数的返回值中),它将自动从以下位置创建std::string对象const char* (如果您不知道,每当您键入"Hello World"它实际上都是const char*值,尽管它通常通过您的代码转换为std::string )。

您可以避免在仍然有一个参数的情况下创建转换构造函数的一种方法(因为自动-aka隐式-转换有时可能很烦人)是将关键字explicit放在构造函数声明的前面,这将告诉编译器不要进行隐式转换-表示无论何时要转换,都必须使用std::string("Hello World")而不是仅使用"Hello World"

希望您能理解我的意思,即使不让我知道! 顺便说一句,我仍然需要验证我对=符号的看法,回到家时,我将使用Visual Studio调试器进行此操作。 我将更新帖子以反映我的发现。

暂无
暂无

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

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