[英]C++ Expected Primary Expression Error
Player::Player(string _name, Room *starting_room)
{
name = _name;
current_room = starting_room;
}
尝试运行/编译“ main.cpp”时出现错误,在下面的构造函数中没有看到任何错误。 但是我仍然遇到以下错误:
错误:“ _ name”之前的预期主表达式
错误:“ *”之前的预期主表达式
错误:无法直接调用构造函数'Player :: Player'[-fpermissive]
注意:对于函数样式转换,请删除多余的':: Player'
错误:在此范围内未声明“ starting_room”
编辑1:播放器类继承自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
所有错误消息都与您显示在现有功能内而不是新功能开始的代码片段一致。 因此,问题在于您在上一个函数的末尾缺少右括号。
这是您进入编译器大脑的方式:
错误:“ _ name”之前的预期主表达式
这意味着编译器希望使用类似2 + 3
的表达式,但是会看到name
。
错误:无法直接调用构造函数'Player :: Player'[-fpermissive]
在这里,它认为您正在尝试调用Player::Player
函数,这与该代码在函数内部而不是新函数一致。
注意:对于函数样式转换,请删除多余的':: Player'
编译器认为您可能正在尝试将string* _name
转换为Player
并使用函数风格的case Player(value)
。
如果您发布的代码是函数主体的一部分,那么这将解释所有这些错误。 编译器不明白你为什么要编写Player::Player(something)
,因为它使一个函数体内没有意义的,它试图提出其他建议,以使一个函数体内感。
第一条线索是对主要表达的讨论。 对于函数声明,您可能会看到的唯一表达式是默认参数。 但是您这里没有人。 那么,为什么编译器要求一个主表达式? 因为它不认为您在编写函数声明。 它认为您正在写声明。
关于您错误地调用函数Player::Player
的建议是您位于函数体内的另一个线索。 通常,您不能在函数主体之外调用函数。 (变量初始化是最明显的例外。)因此,如果编译器试图帮助您调用函数,则它可能会认为您在函数体内。
解决此问题的另一种方法是创建一个最小的,完整的,可验证的示例(MCVE)。 如果这样做,您将注意到删除先前的功能后问题就消失了。 这应该提示您以前的功能可能是问题的根源。
阅读此 。 您绝对应该避免在标题中使用“使用命名空间”。 从每个头文件中将其删除。 我知道您可能总是会写“ std ::”让您感到痛苦,但在这种情况下,请耐心等待。
您可能想为Agent类实现参数构造函数,因此在创建Player之前设置其参数:
Agent(const std::string& _name, Room *const starting_room)
: name(_name), current_room(starting_room) { }
如果希望此构造函数可以受到保护,则只能从派生类(或朋友类)中调用它。 现在,您可以从Player构造函数的初始化部分调用此构造函数:
Player(const std::string&_name, Room *const starting_room)
: Agent(_name, starting_room) { }
注意: name和current_room在Player构造函数主体之前初始化。
这部分是关于改善代码中的几件事:
如果class至少具有1个虚拟方法,则它也应具有虚拟析构函数。 (由于多态性,它应该是虚拟的):
virtual ~Agent() = default;
Getter应该是const限定的,否则您将无法在const对象上调用它们:
std::string getName() const;
覆盖虚拟功能时,请使用覆盖说明符。 这是有用的原因,如果您尝试覆盖非虚函数(错误地),则您的代码将无法编译,因此可以防止出错:
bool act(const std::string&) override;
注意: act是作为虚拟继承的,因此它保持虚拟。 无需再次编写。
考虑返回引用或const引用以避免不必要的复制:
const std::string& getName() const;
始终检查标准库中是否没有任何实现,因此您不必从头开始实现它。 例如toLower函数可以这样写:
// temp is std::string std::transform(temp.begin(), temp.end(), temp.begin(), ::tolower);
注意: std :: transform在算法库中
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.