2016-12-10 62 views
0
Player::Player(string _name, Room *starting_room) 
{ 
    name = _name; 
    current_room = starting_room; 
} 

我有一个错误,当我尝试运行/编译我“的main.cpp”,我看不出有什么错在下面的构造。但我仍然得到这个错误:C++预计初步表达错误

error: expected primary-expression before '_name'

error: expected primary-expression before '*'

error: cannot call constructor 'Player::Player' directly [-fpermissive]

note: for a function-style cast, remove the redundant '::Player'

error: 'starting_room' was not declared in this scope

编辑1:Player类从代理类

//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 
+1

你能提供玩家类吗? –

+0

这可能是因为缺少包含字符串标题和房间定义 – Raindrop7

+0

'Player'两次? –

回答

2

所有的错误消息都与代码片断一致你展示了在现有函数内写入,而不是作为新函数的开始。因此,问题在于您在上一个函数的末尾缺少一个闭合大括号。

这里是你如何让编译器的大脑内部:

error: expected primary-expression before '_name'

这意味着,编译器预计像2 + 3的表达,而是它看到name

error: cannot call constructor 'Player::Player' directly [-fpermissive]

在这里,它认为你正试图调用该函数Player::Player这与该代码的函数里面是不是作为一个新的功能是一致的。

note: for a function-style cast, remove the redundant '::Player'

编译器认为你可能会尝试投放string* _namePlayer和使用函数式表壳Player(value)

如果您发布的代码是函数体的一部分,那么这将解释所有这些错误。编译器不明白你为什么编写Player::Player(something),因为它在函数体内没有任何意义,并且它试图建议在函数体内使用

第一条线索是对主要表达式的讨论。对于函数声明,您可能会看到主表达式的唯一位置是作为默认参数。但你在这里没有一个。那么为什么编译器要求主表达式?因为它不认为你正在写一个函数声明。它认为你正在写一个声明。

建议您错误地调用函数Player::Player是另一个线索,即您在函数体内。通常不能在函数体外调用函数。 (变量初始化是最显着的例外。)所以如果编译器试图帮助你调用一个函数,它可能认为你在函数体内。

尝试解决此问题的另一种方法是创建一个最小,完整,可验证的示例(MCVE)。如果你这样做了,你会注意到当你删除前一个函数时问题就消失了。这应该会引起你以前的功能可能是问题的根源。

+0

这很有帮助,我从来不知道那个错误的含义。现在我做:)再次感谢。 –

+0

@HossamHoussien:由于本文确实回答了您的问题,因此您应该将其标记为已接受的答案。这有助于本网站的未来访问者快速浏览相关信息。 – IInspectable

1

阅读this继承。你一定要避免在标题中使用“using namespace”。从每个头文件中删除它。我知道你可能会发现它总是写“std ::”,但在这种情况下忍受着它。

您可能要实施代理类参数costructor,所以它的参数是在创建播放器之前设置:

Agent(const std::string& _name, Room *const starting_room) 
     : name(_name), current_room(starting_room) { } 

如果你想要这个构造可被保护,它只能从派生类(被称为或朋友)。 现在你可以从播放器的构造函数初始化部分调用此构造:

Player(const std::string&_name, Room *const starting_room) 
     : Agent(_name, starting_room) { } 

注:名和current_room播放器构造函数体之前被初始化。

这部分是关于改善您的代码几件事情:

  1. 如果类具有至少1个虚方法,它应该有虚析构函数 也。 (应该是虚拟的,因为多态):

    virtual ~Agent() = default; 
    
  2. 吸气剂应该是const合格,否则你将无法 称他们在const对象:

    std::string getName() const; 
    
  3. 使用替代符当覆盖虚拟功能时。这是 有用的原因,如果你试图(通过 错误)来覆盖非虚函数的代码不会因此编译它可以防止使 错误:

    bool act(const std::string&) override; 
    

    注:行为被继承的虚拟,所以保持虚拟。没有必要再写一遍。

  4. 想想返回引用或常量引用,以避免不必要的 复制:

    const std::string& getName() const; 
    
  5. 经常检查,如果没有,这样你就不必实现它。从标准库中的任何实施'刮'。例如TOLOWER函数可以写,可以这样写:

    // temp is std::string 
    std::transform(temp.begin(), temp.end(), temp.begin(), ::tolower); 
    

    注:的std ::变换的算法库

+0

这是一个愚蠢的错误,现在它已经修复了。但是我想感谢你指点一些对我来说更重要和“新”的作为初学者。 –

+0

@HossamHoussien不要担心哥们,每个人都会犯错误。我很高兴我能帮上忙!如果你有任何问题随时问。 –

+1

这并不回答问题。 – IInspectable