C ++预期的主表达式错误

时间:2016-12-10 21:38:49

标签: c++ compiler-errors

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

2 个答案:

答案 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构造函数体之前初始化。

这部分是关于改进代码中的一些内容:

  1. 如果类至少有一个虚方法,则它应该具有虚方法 析构函数也是如此。 (由于多态性,它应该是虚拟的):

    std::string getName() const;
    
  2. 吸气剂应该是合格的,否则你将无法胜任 在const对象上调用它们:

    bool act(const std::string&) override;
    
  3. 覆盖虚函数时使用override说明符。它&#39; S 如果您尝试覆盖非虚函数(由 错误)你的代码不会编译,因此它会阻止制作 错误:

    const std::string& getName() const;
    

    注意: act作为虚拟继承,因此保持虚拟。没有必要再写一次。

  4. 考虑返回引用或const引用以避免 不必要的复制:

    // temp is std::string
    std::transform(temp.begin(), temp.end(), temp.begin(), ::tolower);
    
  5. 始终检查标准库中是否有任何实现,因此您不必实施它。来自&#39; scratch&#39;。例如toLower函数可以这样编写:

    int

    注意: std :: transform in in algorithm library