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

У меня есть ошибки, когда я пытаюсь запустить/компилировать мой «main.cpp», я не вижу ничего плохого в приведенном ниже конструктору. Но я все еще получаю эту ошибку:C++ Ожидаемое Primary Expression Error

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: Класс игрока наследует от класса 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 
+1

Вы можете предоставить класс игрока? –

+0

возможно, потому что отсутствует включение заголовка строки и определения комнаты – Raindrop7

+0

'Игрок' дважды? –

ответ

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* _name к Player и пользуясь случаем Player(value) функции стиля.

Если код, который вы отправили, является частью тела функции, тогда это объяснит все эти ошибки. Компилятор не понимает, почему вы пишете Player::Player(something), потому что он не имеет смысла внутри тела функции, и он пытается предложить альтернативы, которые будет иметь смысл внутри тела функции.

Первый ключ - обсуждение первичного выражения. Для объявления функции единственным местом, где вы можете увидеть первичное выражение, является параметр по умолчанию. Но у вас его нет. Итак, почему компилятор запрашивает первичное выражение? Потому что он не думает, что вы пишете объявление функции. Думаю, вы пишете заявление.

Предполагается, что вы неправильно вызываете функцию Player::Player - это еще одна подсказка, что вы находитесь внутри тела функции. Обычно вы не можете вызывать функции вне тела функции. (Переменная инициализация является наиболее заметным исключением.) Поэтому, если компилятор пытается помочь вам вызвать функцию, возможно, вы думаете, что находитесь внутри тела функции.

Еще один способ попытаться решить эту проблему - создать минимальный, полный, проверенный пример (MCVE). Если бы вы это сделали, вы бы заметили, что проблема исчезла, когда вы удалили предыдущую функцию. Это должно вас опрокинуть, что предыдущая функция может быть источником проблемы.

+0

Это было полезно, я никогда не знал, что означает эта ошибка. Теперь я делаю :) Еще раз спасибо. –

+0

@ HossamHoussien: Поскольку этот пост ответил на ваш вопрос, вы должны отметить его как принятый ответ. Это поможет будущим посетителям этого сайта быстро перейти к соответствующей информации. – IInspectable

1

читать this. Вам обязательно следует избегать использования «использования пространства имен» в заголовках. Удалите его из каждого файла заголовка. Я знаю, что вы можете найти боль в заднице, чтобы всегда писать «std ::», но в этом случае нести это.

Вы можете осуществить параметрическую costructor для класса Agent, поэтому его параметры устанавливаются перед созданием проигрывателя:

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. Геттеры должен быть константным квалифицирован, иначе вы не сможете называть их константные объекты:

    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); 
    

    Примечание: станд :: преобразовываться в библиотеке алгоритмов

+0

Это была глупая ошибка, которую я сделал, теперь она исправлена. Но я хотел поблагодарить вас за то, что я указал на что-то более важное и «новое» для меня как новичка. –

+0

@ HossamHoussien не волнуйтесь, приятель, все делают ошибки. Я рад, что смогу помочь! Если у вас есть вопросы, не стесняйтесь спросить. –

+1

Это не отвечает на вопрос. – IInspectable

Смежные вопросы