c++中没有对错误调用的匹配函数
C++ no matching function for call to error
我试着模拟一个特定的游戏作为练习(不要问我哪一个,你会知道如果你知道这个游戏),然而,我只是在网上学习对象和类,整个事情对我来说仍然很困惑。下面是我的一段代码,它给了我一个错误。
我得到的错误是:
C:UsersNDesktopUntitled1.cpp In constructor 'ekop::Moveset::Moveset()':
56 9 C:UsersNDesktopUntitled1.cpp [Error] no matching function for call to 'Move::Move()'
56 9 C:UsersNDesktopUntitled1.cpp [Note] candidates are:
14 3 C:UsersNDesktopUntitled1.cpp [Note] Move::Move(std::string, int, int, int)
14 3 C:UsersNDesktopUntitled1.cpp [Note] candidate expects 4 arguments, 0 provided
11 7 C:UsersNDesktopUntitled1.cpp [Note] Move::Move(const Move&)
11 7 C:UsersNDesktopUntitled1.cpp [Note] candidate expects 1 argument, 0 provided
56 9 C:UsersNDesktopUntitled1.cpp [Error] no matching function for call to 'Move::Move()'
56 9 C:UsersNDesktopUntitled1.cpp [Note] candidates are:
14 3 C:UsersNDesktopUntitled1.cpp [Note] Move::Move(std::string, int, int, int)
14 3 C:UsersNDesktopUntitled1.cpp [Note] candidate expects 4 arguments, 0 provided
11 7 C:UsersNDesktopUntitled1.cpp [Note] Move::Move(const Move&)
11 7 C:UsersNDesktopUntitled1.cpp [Note] candidate expects 1 argument, 0 provided
56 9 C:UsersNDesktopUntitled1.cpp [Error] no matching function for call to 'Move::Move()'
56 9 C:UsersNDesktopUntitled1.cpp [Note] candidates are:
14 3 C:UsersNDesktopUntitled1.cpp [Note] Move::Move(std::string, int, int, int)
14 3 C:UsersNDesktopUntitled1.cpp [Note] candidate expects 4 arguments, 0 provided
11 7 C:UsersNDesktopUntitled1.cpp [Note] Move::Move(const Move&)
11 7 C:UsersNDesktopUntitled1.cpp [Note] candidate expects 1 argument, 0 provided
56 9 C:UsersNDesktopUntitled1.cpp [Error] no matching function for call to 'Move::Move()'
56 9 C:UsersNDesktopUntitled1.cpp [Note] candidates are:
14 3 C:UsersNDesktopUntitled1.cpp [Note] Move::Move(std::string, int, int, int)
14 3 C:UsersNDesktopUntitled1.cpp [Note] candidate expects 4 arguments, 0 provided
11 7 C:UsersNDesktopUntitled1.cpp [Note] Move::Move(const Move&)
11 7 C:UsersNDesktopUntitled1.cpp [Note] candidate expects 1 argument, 0 provided
C:UsersNDesktopUntitled1.cpp In constructor 'ekop::ekop()':
52 12 C:UsersNDesktopUntitled1.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:UsersNDesktopUntitled1.cpp [Error] expected identifier before string constant
62 16 C:UsersNDesktopUntitled1.cpp [Error] expected ',' or '...' before string constant
63 16 C:UsersNDesktopUntitled1.cpp [Error] expected identifier before string constant
63 16 C:UsersNDesktopUntitled1.cpp [Error] expected ',' or '...' before string constant
64 13 C:UsersNDesktopUntitled1.cpp [Error] expected identifier before string constant
64 13 C:UsersNDesktopUntitled1.cpp [Error] expected ',' or '...' before string constant
65 13 C:UsersNDesktopUntitled1.cpp [Error] expected identifier before string constant
65 13 C:UsersNDesktopUntitled1.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类的公共部分:
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
,而默认构造函数提供了这些东西。
str2
和str3
实际上是完全相同调用的不同样式——调用参数化的std::string
构造函数之一(即,在本例中,std::string(const char*)
构造函数)。str3
是相当不言自明的:它就像一个普通的函数调用,只是它是被调用的构造函数,而不是一个普通的函数。str2
显示了c++中一件有趣的事情——当初始化带有=
符号的变量时,它调用构造函数。在本例中,它调用一个转换构造函数,我将对此进行更详细的讨论,但我将等到最后。
最后,str4
不同于其他函数,它实际上调用了两个构造函数(从技术上讲,它是效率最低的)。第一个调用的是std::string("Four")
,它创建一个未命名的std::string
对象,该对象是,然后将传递给std::string
复制构造函数(看起来像std::string(std::string&)
)以创建str4
变量。
它是这样的:创建一个未命名的std::string
对象,并赋予其值"Four"(std::string("Four")
)。然后将该对象传递(还是通过那个古怪的=
符号)给std::string
复制构造函数,将未命名的字符串对象复制到str4
,完成它的创建。请注意,该方法调用了两个构造函数,创建了一个额外的不必要的对象,用于创建str4
。
Now - 转换构造函数。如果类定义了接受单个形参的构造函数,则该构造函数是转换构造函数。因此,基本上,每当该类的对象初始化为可由转换构造函数获取的值时,该值将传递给构造函数,并由构造函数从那里处理它。
转换构造函数没有什么特别的——它们只是普通的构造函数。唯一的区别是,在初始化时不需要括号来调用它,只需要把值放在那里。以std::string(const char*)
构造函数为例。这个构造函数的作用是将const char*
(在C语言时代称为C风格字符串)转换为std::string
对象。使用转换构造函数,您可以将参数值(例如,const char*)放在需要std::string
的任何地方(例如,在函数的返回值中),它将自动从const char*
创建std::string
对象(如果您不知道,每当您键入"Hello World"
之类的东西时,它实际上是const char*
值,尽管它经常被您的代码转换为std::string
)。
有一种方法可以避免在仍然有一个参数的情况下创建转换构造函数(因为自动-又名隐式-转换有时会令人讨厌),那就是在构造函数声明前放置关键字explicit
,这将告诉编译器不要进行隐式转换-这意味着无论何时您想要转换,都必须使用std::string("Hello World")
而不仅仅是"Hello World"
。
希望你明白我在说什么,如果不只是让我知道!顺便说一下,我仍然需要验证我所说的关于=
标志的内容,当我回家时,我将使用Visual Studio调试器来做。我将更新这篇文章来反映我的发现。
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 函数调用C++中的参数太少
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 返回指向对象的指针的函数调用是否为 prvalue?
- C++ 如何重载 [] 运算符并进行函数调用
- 代码的效率. 转到和函数调用
- 是同一作用域的函数部分中的函数调用
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 类型擦除的std::function与虚拟函数调用的开销