2016-12-10 75 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