Sign in to follow this  
bedtime

error: ‘filename’ was not declared in this scope

Recommended Posts

bedtime    159
I seem to run into this issue where I try to use seperate file compilation and I end up getting the message:

[quote]error: ‘Component’ was not declared in this scope[/quote]

I've declared the Component file, but I think this is a cyclic issue of some sort. Is there a way that I can avoid this problem?

Here are the files:

[source lang="cpp"]// main.cpp
#include <iostream>
#include <string>
#include "gameobject.h"
#include "component.h"

int main ()
{

GameObject* go = new GameObject("Player");
Component* gun = new Component;

go->AddComponent(gun);

}
[/source]


[source lang="cpp"]#ifndef COMPONENT_H
#define COMPONENT_H
#include <iostream>
#include <string>
#include "gameobject.h"

class Component
{
public:

std::string name; //The name of the component
bool enabled; //Is the component currently enabled?
GameObject* gameObject; //The game object that owns this component
int type; //The type of component

//Initializing Ctor
Component(std::string Name) : name(Name), enabled(true) {}

//Dtor
virtual ~Component() {}

//Abstract function, called when the scene is started
virtual void OnStart() = 0;
//Abstract function, called when the scene is updated
virtual void OnUpdate() = 0;
};

#endif // COMPONENT_H
[/source]


[source lang="cpp"]#ifndef GAMEOBJECT_H
#define GAMEOBJECT_H
#include <iostream>
#include <vector>
#include <string>
#include "component.h"

class GameObject
{
// ERROR STARTS AT CODE BELOW (notice 'component.h' is declared above):

std::vector<Component> components; //A list of components attached to the game object

public:
std::string name; //The unique name of the game object
//Transform transform; //The object's transform

//Initializing Ctor
GameObject(std::string Name = "Default Player") : name(Name) { }
~GameObject() { }

//Finds the attached component with the name Name (if it exists)
/* Component* GetComponent(std::string Name)
{

}

//Finds the attached component with the index Idx (if it exists)
Component* GetComponentAt(int Idx)
{

}*/

//Attaches a component to the game object
void AddComponent(Component* NewComponent)
{
components.push_back(*NewComponent);
}

//Detaches the component with the name Name (if it exists)
void RemoveComponent(std::string Name)
{

}

//Detaches the component with the index Idx (if it exists)
void RemoveComponentAt(int Idx)
{

}

//Initializes the game object by initializing each of its attached components
void Start() {}
//Updates the game object by updating each of its attached components
void Update() {}

};

#endif // GAMEOBJECT_H
[/source]

Share this post


Link to post
Share on other sites
SiCrane    11839
You might want to read this article: [url=http://www.gamedev.net/page/resources/_/technical/general-programming/organizing-code-files-in-c-and-c-r1798]Organizing Code Files in C and C++[/url]. You have problem number two from that article.

Share this post


Link to post
Share on other sites
bedtime    159
[quote name='SiCrane' timestamp='1353774940' post='5003768']
You might want to read this article: [url="http://www.gamedev.net/page/resources/_/technical/general-programming/organizing-code-files-in-c-and-c-r1798"]Organizing Code Files in C and C++[/url]. You have problem number two from that article.
[/quote]

Thank you so much for the quick response!

I read and found the answer. Excellent article. I found the issue and fixed it. Here is the advice for anyone that might want a quick glimpse at the answer:

[i]quoted from article[/i]

[quote]There are more in-depth ways of resolving cyclic dependencies, but they are beyond the scope of this article. In 99% of cases, using forward declarations and favoring normal functions in C./.CPP files over inline functions in header files will be enough.[/quote]

Working code:

[source lang="cpp"]#ifndef GAMEOBJECT_H
#define GAMEOBJECT_H
#include <iostream>
#include <vector>
#include <string>
//#include "component.h"

class Component;

class GameObject
{
std::vector<Component*> components; //A list of components attached to the game object

public:
std::string name; //The unique name of the game object
//Transform transform; //The object's transform

//Initializing Ctor
GameObject(std::string Name = "Default Player") : name(Name) { }
~GameObject() { }

//Finds the attached component with the name Name (if it exists)
/* Component* GetComponent(std::string Name)
{

}

//Finds the attached component with the index Idx (if it exists)
Component* GetComponentAt(int Idx)
{

}*/

//Attaches a component to the game object
void AddComponent(Component* NewComponent)
{
components.push_back(NewComponent);
}

//Detaches the component with the name Name (if it exists)
void RemoveComponent(std::string Name)
{

}

//Detaches the component with the index Idx (if it exists)
void RemoveComponentAt(int Idx)
{

}

//Initializes the game object by initializing each of its attached components
void Start() {}
//Updates the game object by updating each of its attached components
void Update() {}

};

#endif // GAMEOBJECT_H[/source]

Share this post


Link to post
Share on other sites
bedtime    159
Edit,


still not working... sigh




I've been at this for a day now and no progress. I read the article and I've still not got this other part of the code to work. I appear to have an issue with my Map object not being being recognised even though i've declared it and its within the same class. I've tried the map object as a pointer as suggested in the link (its not a pointer because i dont feel like changing all the other stuff around by adding the arrow insertion operator for the 5th time.... Pointer or not both result in seg faults. Out of everything in c++ these cyclic dependancies are the holding my code back the most. This is really quite frustrating. The article said in 99% of cases adding a forward declaration and pointer to object of another class is enough. I'm missing something.

Here is the code:

[source lang="cpp"]
// game.h
#ifndef GAME_H
#define GAME_H
#include <map>
#include <vector>
#include "staticcount.h"
#include "value.h"
#include "tvalue.h"


class GameObject;

typedef std::pair<int, int> Key;

class Game
{

Value value;

std::multimap<std::pair<int, int>, GameObject*> Map;

std::multimap<std::pair<int, int>, GameObject*> go2;

// x chunk, y chunk, gameObject
std::multimap<int, std::multimap<int, GameObject*>*> go;

public:

Game() { value.newNum("game number", StaticCount::getNumGames()->getNum()); }

// get game values
Value* val() { return &value; }

void loop(int x_begin, int x_end, int y_begin, int y_end);

std::multimap<std::pair<int, int>, GameObject*> getMap();

};

#endif[/source]


[source lang="cpp"]// game.cpp
#include <iostream>
#include "game.h"
#include "gameobject.h"
#include "keys.h"


std::multimap<std::pair<int, int>, GameObject*> Game::getMap()
{


return Map;
}

void Game::loop(int x_begin, int x_end, int y_begin, int y_end)
{

/* uncommenting the line below makes the code below works but its useless
as it goes out of scope and is not stored. if the line is commented i
get a seg fault */

//std::multimap<std::pair<int, int>, GameObject*> Map;


GameObject* gameObj1 = new GameObject;
gameObj1->val()->setNum("test", 10);

// seg fault is from the line below: (this works if above code 6 lines above is uncommented)
Map.insert({std::make_pair<int, int>(1, 2), gameObj1});

std::cout << "made this far" << std::endl;

GameObject* gameObj2 = new GameObject;
gameObj2->val()->setNum("test", 20);
Map.insert({std::make_pair<int, int>(3, 4), gameObj2});

GameObject* gameObj3 = new GameObject;
gameObj3->val()->setNum("test", 30);
Map.insert({std::make_pair<int, int>(5, 10), gameObj3});


x_begin = 2;
y_begin = 1;
x_end = 5;
y_end = 9;

x_end++;
y_end++;

// if (x_end <= x_begin) return;
// if (y_end <= y_begin) return;

Key lower(x_begin, y_begin);
Key upper(x_end - 1, y_end);
auto first = Map.lower_bound(lower);
auto last = Map.lower_bound(upper);

for (auto itr = first; itr != last;)
{

int x = itr->first.first;
int y = itr->first.second;

if (y < y_begin)
{
itr = Map.lower_bound(Key(x, y_begin));
}
else if (y >= y_end)
{
itr = Map.lower_bound(Key(x + 1, y_begin));
}
else
{

std::cout << "x: " << x << " y: " << y <<" test: " <<
itr->second->val()->getNum("test")
<< std::endl;


++itr;
}
}
}
[/source] Edited by bedtime

Share this post


Link to post
Share on other sites
bedtime    159
[quote name='RulerOfNothing' timestamp='1354070900' post='5004803']
Why do you have braces in the line:
Map.insert({std::make_pair<int, int>(1, 2), gameObj1}); ?
[/quote]
I'm not sure how to get the code to work without them. I get a compile time error.

I just tried changing the code to:

[source lang="cpp"]getMap()->insert(std::make_pair(std::make_pair(1,2), gameObj1));
[/source]
its okay just inserting the once, but if I repeat the code above or try to access getMap() again it seg faults. Edited by bedtime

Share this post


Link to post
Share on other sites
SiCrane    11839
[quote name='bedtime' timestamp='1354069769' post='5004793']
I've been at this for a day now and no progress. I read the article and I've still not got this other part of the code to work.
[/quote]
The purpose of the article is to get your code to compile and link when using multiple source and header files. Following those directions doesn't prevent other kinds of problems to show up in your code. If your code even gets to the point where it can run then your problem isn't related to the article.

[quote]I appear to have an issue with my Map object not being being recognised even though i've declared it and its within the same class.[/quote]
If it wasn't being recognized it wouldn't even compile. The fact that it does compile means that it is being recognized. Since the problem is a run time error when accessing the Map variable then most likely the problem is that you aren't initializing your object properly. If that isn't enough of a hint to get your program working properly, try producing a minimal, but complete code sample that demonstrates your problem.

[quote name='RulerOfNothing' timestamp='1354070900' post='5004803']
Why do you have braces in the line:
Map.insert({std::make_pair<int, int>(1, 2), gameObj1}); ?
[/quote]
That's a C++11 feature: uniform initialization.

Share this post


Link to post
Share on other sites
bedtime    159
[quote name='SiCrane' timestamp='1354075943' post='5004831']
[quote name='bedtime' timestamp='1354069769' post='5004793']
I've been at this for a day now and no progress. I read the article and I've still not got this other part of the code to work.
[/quote]
The purpose of the article is to get your code to compile and link when using multiple source and header files. Following those directions doesn't prevent other kinds of problems to show up in your code. If your code even gets to the point where it can run then your problem isn't related to the article.

[quote]I appear to have an issue with my Map object not being being recognised even though i've declared it and its within the same class.[/quote]
If it wasn't being recognized it wouldn't even compile. The fact that it does compile means that it is being recognized. Since the problem is a run time error when accessing the Map variable then most likely the problem is that you aren't initializing your object properly. If that isn't enough of a hint to get your program working properly, try producing a minimal, but complete code sample that demonstrates your problem.

[quote name='RulerOfNothing' timestamp='1354070900' post='5004803']
Why do you have braces in the line:
Map.insert({std::make_pair<int, int>(1, 2), gameObj1}); ?
[/quote]
That's a C++11 feature: uniform initialization.
[/quote]

Thanks. I solved it. It was something to do with dereferencing and not using 'new' to declare my game object.

Sorry for my constant posts. Today has just been a frustrating day for me, much more then usual and I'm sitting here with a headache... I've been at this way too long today. Maybe 14 hours. Brain went to mush several hours ago.

Anyways, you guys have all been so helpful.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this