Player::Player(string _name, Room *starting_room)
{
name = _name;
current_room = starting_room;
}
当我尝试运行/编译“main.cpp”时出错,我在下面的构造函数中没有看到任何错误。但我仍然遇到这个错误:
错误:在'_name'之前预期的primary-expression
错误:在'*'
之前预期的primary-expression错误:无法直接调用构造函数'Player :: Player'[-fpermissive]
注意:对于函数式转换,删除多余的“:: Player”
错误:此范围内未声明'starting_room'
编辑1:Player类继承自Agent类
//Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include<string>
#include "Room.h"
#include "Agent.h"
using namespace std;
class Player: public Agent
{
public:
Player();
Player(string _name, Room *starting_room);
virtual bool act(string direction);
};
#endif // PLAYER_H
//"Agent.h"
#ifndef AGENT_H
#define AGENT_H
#include <Room.h>
#include<string>
using namespace std;
class Agent
{
protected:
Room *current_room;
string name;
public:
Agent();
virtual bool act(string) ;
string getName();
string getCurrentRoomName();
string toLower(string temp);
Room* getCurrentRoom();
};
#endif // AGENT_H
答案 0 :(得分:2)
所有错误消息都与您在现有函数中写入的代码片段一致,而不是作为新函数的开头。因此,问题是你在上一个函数的末尾缺少一个闭括号。
以下是你如何进入编译器的大脑:
错误:在'_name'之前预期的primary-expression
这意味着编译器需要2 + 3
这样的表达式,而是看到name
。
错误:无法直接调用构造函数'Player :: Player'[-fpermissive]
在这里,它认为你试图调用函数Player::Player
,这与函数中的代码一致,而不是一个新函数。
注意:对于函数式转换,删除多余的“:: Player”
编译器认为您可能正在尝试将string* _name
投射到Player
并使用函数式案例Player(value)
。
如果您发布的代码是函数体的一部分,那么这将解释所有这些错误。编译器不理解为什么要编写Player::Player(something)
,因为它在函数体内没有任何意义,并且它试图建议在函数体内 有意义的替代方法。
第一个线索是对主要表达的讨论。对于函数声明,您可能看到主表达式的唯一位置是默认参数。但你这里没有。那么编译器为什么要求主表达式呢?因为它不认为你正在写一个函数声明。它认为你正在写一份声明。
您错误地调用函数Player::Player
的建议是您在函数体内的另一个线索。您通常无法在函数体外调用函数。 (变量初始化是最值得注意的例外。)因此,如果编译器试图帮助您调用函数,它可能会认为您在函数体内。
尝试解决此问题的另一种方法是创建一个最小的,完整的,可验证的示例(MCVE)。如果你这样做了,你会注意到当你删除上一个函数时问题就消失了。这应该会让你知道前一个函数可能是问题的根源。
答案 1 :(得分:1)
阅读this。你绝对应该避免使用&#34;使用命名空间&#34;在标题中。从每个头文件中删除它。我知道你可能会发现总是写'#34; std ::&#34;'会很痛苦,但在这种情况下请耐心等待。
您可能希望为Agent类实现参数化构造函数,因此在创建Player之前设置其参数:
Player(const std::string&_name, Room *const starting_room)
: Agent(_name, starting_room) { }
如果您希望此构造函数可以受到保护,那么只能从派生类(或朋友类)调用它。 现在,您可以从Player构造函数的初始化部分调用此构造函数:
virtual ~Agent() = default;
注意: name和current_room在Player构造函数体之前初始化。
这部分是关于改进代码中的一些内容:
如果类至少有一个虚方法,则它应该具有虚方法 析构函数也是如此。 (由于多态性,它应该是虚拟的):
std::string getName() const;
吸气剂应该是合格的,否则你将无法胜任 在const对象上调用它们:
bool act(const std::string&) override;
覆盖虚函数时使用override说明符。它&#39; S 如果您尝试覆盖非虚函数(由 错误)你的代码不会编译,因此它会阻止制作 错误:
const std::string& getName() const;
注意: act作为虚拟继承,因此保持虚拟。没有必要再写一次。
考虑返回引用或const引用以避免 不必要的复制:
// temp is std::string
std::transform(temp.begin(), temp.end(), temp.begin(), ::tolower);
始终检查标准库中是否有任何实现,因此您不必实施它。来自&#39; scratch&#39;。例如toLower函数可以这样编写:
int
注意: std :: transform in in algorithm library