C++ C++;没有用于调用错误的匹配函数

C++ C++;没有用于调用错误的匹配函数,c++,class,object,c++11,C++,Class,Object,C++11,我试着模拟一个特定的游戏作为练习(不要问我哪一个,如果你知道这个游戏,你就会知道),然而,我只是在互联网上学习了对象和类,整个事情仍然让我感到困惑。下面是我的代码中给出错误的部分 我的错误是: C:\Users\N\Desktop\Untitled1.cpp In constructor 'ekop::Moveset::Moveset()': 56 9 C:\Users\N\Desktop\Untitled1.cpp [Error] no matching function f

我试着模拟一个特定的游戏作为练习(不要问我哪一个,如果你知道这个游戏,你就会知道),然而,我只是在互联网上学习了对象和类,整个事情仍然让我感到困惑。下面是我的代码中给出错误的部分

我的错误是:

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
我不知道出了什么问题,代码如下。 不要告诉我不要使用
名称空间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;
}
编辑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类的public部分:

Move() {
    //Give fields default values here
}
当您在未初始化变量的情况下声明变量时,它会调用默认构造函数(不带参数的构造函数)来为变量提供默认值,直到使用为止。有时保留这些默认值,有时为其指定新对象。。但这取决于你想做什么,而不是真正相关的

<>编辑:好的,所以,在C++中有两种方法来声明变量。我将使用std::string作为示例,但这适用于任何类型(即使是基本类型,尽管它们的类本身并没有定义,而只是内置在语言中):

str1
只是一个声明,其余的是声明和初始化(它们声明变量,然后给它一个初始值)

str1
调用默认构造函数,因为没有提供初始值。因此,编译器需要分配给str1的内容,而默认构造函数提供了该内容

str2
str3
实际上是完全相同调用的不同样式-对参数化
std::string
构造函数之一的调用(即,在本例中,
std::string(const char*)
构造函数)<代码>str3
是相当不言自明的:它就像一个普通的函数调用,只是调用的是构造函数,而不是普通的函数<代码> STR2显示了一个有趣的C++,当用 = /Cuth>符号初始化变量时,它调用构造函数。在本例中,is调用了一个转换构造函数,我将更详细地介绍它,但我将等到最后

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

它是这样的:一个未命名的
std::string
对象被创建,并被赋予值“Four”(
std::string(“Four”)
)。然后将该对象(再次通过奇怪的
=
符号)传递给
std::string
copy构造函数,将未命名的string对象复制到
str4
,完成其创建。请注意,此方法调用两个构造函数,创建一个额外的不必要对象,用于创建
str4

现在-转换构造函数。如果一个类定义了一个接受单个参数的构造函数,那么该构造函数就是一个转换构造函数。因此,基本上,每当该类的对象被初始化为一个值,该值可以由转换构造函数获取,该值就会被传递给构造函数,构造函数就会从那里处理它

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

有一种方法可以避免在仍然有转换构造函数的情况下创建转换构造函数
Move() {
    //Give fields default values here
}
std::string str1;
std::string str2 = "Two";
std::string str3("Three");
std::string str4 = std::string("Four");