Search code examples
c++vectorundeclared-identifier

undeclared identifier, object vector


I am getting an error and I don't know how to fix it. I checked everything and maybe I overlooked something, but I am not able to find the problem.

Errors:

1>------ Build started: Project: Aquarium, Configuration: Release x64 ------
1>  Fish.cpp
1>c:\users\lloyd17\dropbox\aquarium project\aquarium\aquarium\EntityControl.h(21): error C2065: 'Fish': undeclared identifier
1>c:\users\lloyd17\dropbox\aquarium project\aquarium\aquarium\EntityControl.h(21): error C2059: syntax error: '>'
1>c:\users\lloyd17\dropbox\aquarium project\aquarium\aquarium\EntityControl.h(21): error C2976: 'std::vector': too few template arguments
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\vector(682): note: see declaration of 'std::vector'
1>c:\users\lloyd17\dropbox\aquarium project\aquarium\aquarium\EntityControl.h(24): error C2061: syntax error: identifier 'Fish'
1>  LooseCalculationClass.cpp
1>c:\users\lloyd17\dropbox\aquarium project\aquarium\aquarium\EntityControl.h(21): error C2065: 'Fish': undeclared identifier
1>c:\users\lloyd17\dropbox\aquarium project\aquarium\aquarium\EntityControl.h(21): error C2059: syntax error: '>'
1>c:\users\lloyd17\dropbox\aquarium project\aquarium\aquarium\EntityControl.h(21): error C2976: 'std::vector': too few template arguments
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\vector(682): note: see declaration of 'std::vector'
1>c:\users\lloyd17\dropbox\aquarium project\aquarium\aquarium\EntityControl.h(24): error C2061: syntax error: identifier 'Fish'
1>LooseCalculationClass.cpp(7): warning C4551: function call missing argument list
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Fish.h

#pragma once
#include <iostream>
#include <string>
#include "EntityControl.h"
class Fish
{

private:
    //location of the fish
    unsigned int _xLocation = 0, _yLocation = 0, _zLocation = 0;
    //name of fish
    std::string nameOfFish;
    unsigned int speed;
public:
    //constructor
    Fish(std::string name, unsigned int fishSpeed)
    {
        nameOfFish = name;
        speed = fishSpeed;

    }   

    //getters
    int getX() const;
    int getY() const;
    int getZ() const;
    std::string getName() const;
    void changeX(unsigned int x);
    void changeY(unsigned int y);
    void changeZ(unsigned int z);

    void move();



    ~Fish();
};

Fish.cpp

#include "Fish.h"


int Fish::getX() const
{
    return _xLocation;
}

int Fish::getY() const
{
    return _yLocation;
}

int Fish::getZ() const
{
    return _zLocation;
}

std::string Fish::getName() const
{
    return nameOfFish;
}

void Fish::changeX(unsigned int x)
{
    _xLocation = x;
}

void Fish::changeY(unsigned int y)
{
    _yLocation = y;
}

void Fish::changeZ(unsigned int z)
{
    _zLocation = z;
}

void Fish::move()
{
    EntityControl entity;
    unsigned int x = rand() % entity.getXContainer();
    unsigned int y = rand() % entity.getYContainer();
    unsigned int z = rand() % entity.getZContainer();


}


Fish::~Fish()
{
}

Aquarium.cpp(Main)

using namespace std;
#include "EntityControl.h"
#include <Windows.h>
#include <time.h>
#include "LooseCalculationClass.h"
#include <thread>
#include "Fish.h"



int main() {
    /*Not using new in object definitions so I don't have to delete them afterwards since pointers don't stay in memory*/
    bool running = true;
    //defining my objects for functions
    EntityControl entity;
    LooseCalculationClass calc;
    vector<Fish*> fishVector;
    Fish a("Lloyd", 200);
    fishVector.push_back(&a);
    std::thread t1(&EntityControl::movementController, entity, &fishVector);
    //std::thread t2(&LooseCalculationClass::userInput, calc);
    //t2.detach();
    t1.detach();


    //main gameloop, prints out the results for every fish, waits a bit and then refreshes the screen
        while(running){
            for (auto Fish_ptr : fishVector) {
                calc.printOutXYZ(*Fish_ptr);
                Sleep(500000);
                system("pause");
                //system("cls");

            }
    }
     return 0;
}

EntityControl.h

#pragma once
#include <iostream>
#include <vector>
#include "Fish.h"
#include <random>
#include <array> 
#include <Windows.h>

class EntityControl
{
private:    
/*Didn't make a separate object because I only 
needed the x,y,z of the fish container although it is against the rules of object oriented programming*/
    const unsigned int _xContainer = 20;
    const unsigned int _yContainer = 60;
    const unsigned int _zContainer = 40;
public:
    /*grabs the location of a vector of fish pointers, then takes the 
    vector and accesses every object threw it's data location with dereferencing.
    (Controls the movement of the fish and prevents collision)*/
    void movementController(std::vector<Fish*> *fishInputVector);//thread!!

    //ACHTUNG! fishInput is the fish to check the surrounding of, changing this might bring up unexpected errors
    bool CheckCollision(Fish* fishInput , Fish* fishInput2);

    int getXContainer() const;
    int getYContainer() const;
    int getZContainer() const;

    ~EntityControl();
};

EntityControl.cpp

#include "EntityControl.h"

    /*if the container was much larger,
    then multiple threads would be a better solution*/ 
void EntityControl::movementController(std::vector<Fish*> * fishInputVector)
{
    while (true) {


        for (auto fish_ptr : *fishInputVector) {
        }
    }
}

bool EntityControl::CheckCollision(Fish * fishInput, Fish * fishInput2)
{
    //collision true/false
    bool collision = false;

    //collision detectors
    bool xCollision = false;
    bool yCollision = false;
    bool zCollision = false;

    //fishInput
    unsigned int xOriginal = fishInput->getX();
    unsigned int yOriginal = fishInput->getY();
    unsigned int zOriginal = fishInput->getZ();

    //fishInput2
    unsigned int xEntity = fishInput2->getX();
    unsigned int yEntity = fishInput2->getY();
    unsigned int zEntity = fishInput2->getZ();

    //directions, (triggerBox)
    if (xOriginal - 1 == xEntity || xOriginal + 1 == xEntity || xOriginal == xEntity) { xCollision = true; }
    if (yOriginal - 1 == yEntity || yOriginal + 1 == yEntity || yOriginal == yEntity) { yCollision = true; }
    if (zOriginal - 1 == zEntity || zOriginal + 1 == zEntity || zOriginal == zEntity) { zCollision = true; }


    //returns true if all 3 directions are true
    if (xCollision && yCollision && zCollision) { collision = true; }

    return collision;
}


int EntityControl::getYContainer() const
{
    return _yContainer;
}

int EntityControl::getXContainer() const
{
    return _xContainer;
}

int EntityControl::getZContainer() const
{
    return _xContainer;
}

EntityControl::~EntityControl()
{
}

It worked before, don't know exactly what has changed. I think everything is declared like it should but this has been bothering me for a while. Putting the classes in another project and running it from there didn't work either. Neither did changing around some variables / removing methods, but again, I might have missed something.


Solution

  • The problem is that when you include EntityControl.h you have also included Fish.h which refers to Fish defined in Fish.h. However EntityControl.h refers to Fish.h which won't get included because of the pragma once directive. If you remove pragma once then you'd get an infinite loop because of circular dependency.

    To solve the problem of circular dependencies use forward declarations. Remove #include "EntityControl.h" from Fish.h and write class EntityControl; instead.

    You may also remove #include "Fish.h"; from EntityControl.h and write class Fish; in its stead.