2014-11-06 2 views
0

Мне не нравится публиковать что-то настолько тонкое, но это меня полностью затормозило от того, что я делаю неправильно: Когда я компилирую, это не нравится Simulator классов вообще. Я получаю сообщение об ошибкеОшибка синтаксиса: идентификатор (ошибка C2061)

syntax error : identifier 'Simulator' 

В каждом экземпляре Simulator я использую внутри заголовочного файла DOCO. Он также делает это для моей структуры Pellet. Код работал полностью нормально, пока я не начал добавлять функции, которые работают с классом Simulator внутри DOCO.h. Класс Simulator использует структуру DOCO, а структура DOCO использует класс Simulator. Это проблема? Может быть, я использовал в своих заголовках неправильно?

Вот ссылка на ошибки я получаю, если это поможет: http://msdn.microsoft.com/en-us/library/yha416c7.aspx

#include <iostream> 
#include <conio.h> 
#include <string> 
#include "Simulator.h" //<---Has a chain of includes for other header files 
int main() 
{ 
    RandomNumberGen R; 
    Simulator S; 
    Pellet P; 
    DOCO D; 

    system("pause"); 
    return 0; 
} 

Заголовок Файлы: Simulator.h

#pragma once 
#include <iostream> 
#include <stdio.h> 
//#include <conio.h> 
#include <vector> 
#include "Pellet.h" 
#include "DataParser.h" 
#include "DOCO.h" 
#include "RandomNumberGen.h" 
#include "Cell.h" 
#include "Timer.h" 

using namespace std; 

class Simulator 
{ 
private: 
    int s_iDocoTotal; 
    int s_iPelletTotal; 
    int s_iGridXComponent; 
    int s_iGridYComponent; 
    int tempX; 
    int tempY; 

    //Pellet P; 
    //DOCO D; 


    static const unsigned int s_iNumOfDir=8; 


public: 
    Simulator(); 
    ~Simulator(); 

    //int GenerateDirection(); 
    void InitiateDOCO(RandomNumberGen *R, DOCO *D, vector<DOCO>&); // 
    void SpreadFood(RandomNumberGen *R, Pellet *P, vector<Pellet>&, const int x, const int y);  // 
    void AddPellet(Pellet *P, RandomNumberGen *R);   // 
    void CheckClipping(Pellet *P, RandomNumberGen *R);  // 
    void CheckPellets(Pellet *P, RandomNumberGen *R);  // 
    void CreateGrid(int x, int y);// 
    int GetGridXComponent(); // 
    int GetGridYComponent(); // 
    int GetDocoTotal(); 
    vector<DOCO> docoList;     //Holds the Doco coordinates 
    vector<Pellet> pelletList;    //!!Dont use this!! For data import only 
    vector<vector<int> > pelletGrid; //Holds X-Y and pellet count 
    char **dataGrid;  //Actual array that shows where units are 

    Simulator(const int x, const int y) : 
       s_iGridXComponent(x), 
       s_iGridYComponent(y), 
       pelletGrid(x, vector<int>(y)){} 
}; 

DOCO.h

#pragma once 
#include <iostream> 
#include <stdio.h> 
#include <vector> 
#include "Simulator.h" 
//#include "DataParser.h" 



using namespace std; 

struct DOCO 
{ 
private: 
    int d_iXLocation; 
    int d_iYLocation; 
    int d_iEnergy; 
    int d_iMovement; 
    int d_iTemp; 
    //Simulator S; 
    //RandomNumberGen R; 
    //Pellet P; 
    enum Direction { NORTH, SOUTH, EAST, WEST, NORTHWEST, NORTHEAST, SOUTHWEST, SOUTHEAST}; 


public: 
    DOCO(); 
    ~DOCO(); 
    //int a is the position in docoList to reference DOCO 
    int GoNorth(Simulator *S, int a); 
    int GoSouth(Simulator *S, int a); 
    int GoEast(Simulator *S, int a); 
    int GoWest(Simulator *S, int a); 
    int GoNorthWest(Simulator *S, int a); 
    int GoNorthEast(Simulator *S, int a); 
    int GoSouthWest(Simulator *S, int a); 
    int GoSouthEast(Simulator *S, int a); 

    //int a is the position in docoList to reference DOCO 
    void Sniff(Simulator *S, RandomNumberGen *R, int a);  //Detects DOCOs and food 
    void Reroute(Simulator *S, RandomNumberGen *R, int a); //Changes DOCO direction 
    void SetDOCO(int tempX, int tempY, int tempEnergy, int tempMovement); 
    int GetEnergy(); // 
    int SetEnergy(); 
    int SetMovement(); 
    int GetMovement(); // 
    int GetXLocation(); // 
    int GetYLocation(); // 
    void SetXLocation(int d_iTemp); 
    void SetYLocation(int d_iTemp); 
    void EatPellet(Pellet *P, Simulator *S, int a);//ADD DOCO ARGUMENT/DONT OVERLAP DOCO AND PELLETS 
    void MoveDoco(Simulator *S, int a); 
    void Death(); 
}; 
+0

Вы включаете эти заголовочные файлы в main.cpp? – radar

+0

Ницца с запуском и копией, как вы это сделали? – Surt

+0

Я вижу функцию main() без '# include'. Поэтому, конечно, компилятор будет жаловаться, когда вы представите что-то вроде «Симулятора» из этого синего. Кроме того, нет необходимости повторять ключевые слова 'class' и' struct' при создании экземпляра. – PaulMcKenzie

ответ

0

Как мой комментарий выше, ваша проблема связана с рекурсивным включением.

Вы можете сделать одну из двух вещей:

1) Измените класс Simulator, так что вы используете ссылки на DOCO или указатели на DOCO, и, таким образом, forward declare DOCO.

2) Измените заголовок DOCO на использование указателей на Simulator или ссылки на Simulator, а затем просто отправьте объявление Simulator.

Самый простой изменить (если эти комментарии в коде остаются), чтобы изменить DOCO.h:

#pragma once 
#include <iostream> 
#include <stdio.h> 
#include <vector> 

class Simulator; 

struct DOCO 
{ 
... 
}; 

Внутри определения DOCO структуры, вы можете указать ссылки и указатели на Simulator, не Simulator объектов.

Я также рекомендую не положить using namespace std; в заголовочный файл. Это обсуждается во многих потоках здесь, на SO о том, почему вы не должны иметь эту строку в своем файле заголовка.

+0

'using namespace std;' в заголовках - это зло, хорошая точка. – Surt

0

I «Конечно, вы не хотели называть объявлять классы.

int main() 
 
{ 
 
\t RandomNumberGen R; 
 
\t Simulator S; 
 
\t Pellet P; 
 
\t DOCO D; 
 
    
 
    system("pause"); 
 
\t return 0; 
 
}

+0

Учитывая видимый класс 'RandomNumberGen', вполне законно обращаться к типу как' class RandomNumberGen'. Проблема в том, что (при условии, что это весь исходный файл) имена классов не видны. Удаление ключевых слов 'class' и' struct' просто изменяет сообщение об ошибке. –

+0

Даже при удалении ключевых слов struct и class в main() у меня есть ошибка. Что касается видимости, другие исходные файлы указывают на структуру (или класс) при ее использовании. Например: void CheckClipping (Pellet * P, RandomNumberGen * R); – AbductedMonkey

+0

@AbductedMonkey Как я уже говорил выше, ваша проблема связана с рекурсивным включением. Вам нужно изменить свой класс Simulator, чтобы вы использовали ссылки на DOCO или указатели на DOCO и, таким образом, «forward declare» DOCO. – PaulMcKenzie

0

После ваших директив #includes в файле Simulator.h, добавьте строку

struct DOCO; 

После директив #includes в файле Doco.h, добавьте строку

class Simulator; 

Это говорит о том, что c ompiler, хотя несмотря на то, что при компиляции файла Simulator он еще не знает, что такое DOCO, он в конечном итоге все понял. Аналогично для компиляции файла DOCO.

Когда вы переадресовываете такой класс, вы не можете создавать экземпляры этого класса до тех пор, пока класс не будет определен. Однако вы можете создавать указатели или ссылки на этот класс. Поэтому, если ваша структура DOCO должна иметь симулятор и наоборот, сделайте их содержащими элементы указателя, а не членами объекта.