Public Group

# Please refresh my knowledge of forward declarations...

This topic is 2595 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Ok, so I have two classes that need to know about each other:

#ifndef __SCENEMANAGER_H__ #define __SCENEMANAGER_H__ #pragma once #include <vector> #include <string> #include <log4cplus/logger.h> #include <log4cplus/configurator.h> using namespace log4cplus; using namespace std; //Forward declaration, to avoid having to include "UIScene.h". class UIScene; class SceneManager { private: vector<UIScene> m_Scenes; public: void LoadInitialScreen(string Path); void AddScreen(UIScene Screen); }; #endif

#ifndef __UISCENE_H__ #define __UISCENE_H__ #pragma once #include <vector> #include <string> #include "UIBackground.h" #include "SceneManager.h" #include "libfar.h" using namespace std; class UIScene { private: string m_ArchivePath; SceneManager m_SceneMgr; vector<UIBackground> m_Backgrounds; public: UIScene(SceneManager SceneMgr, string ArchivePath); void LoadBackground(int ID); }; #endif

SceneManager.h compiles perfectly, and I didn't really have a problem until I added the method AddScreen(UIScene Screen) to ScreenManager.

void SceneManager::AddScreen(UIScene Screen) { m_Scenes.push_back(Screen); }

This code (in SceneManager.cpp) gives me the following error:

Error 1 error C2027: use of undefined type 'UIScene

Even though UIScene has been forwardly declared in 'SceneManager.h'!
What gives?

##### Share on other sites
As far as I know you can NOT use whole Classes in your header with forward declarations.

If I am right, the problem occurs due to the fact that classes have different sizes and the compiler does not know the size of UIScene because you declare it forwardly.

You can fix this Problem by taking pointers of UIScene instead of the whole class. Pointers always have the same size.

Hope this helps.

greetings

Fabbo

Edit: you just have to do one of the include guards. You can choose
#pragma once
or you can choose
 #ifndef __UISCENE_H__ #define __UISCENE_H__ //stuff here #endif 

##### Share on other sites

I changed the method to:

void SceneManager::AddScreen(UIScene *Screen) { m_Scenes.push_back(*Screen); }

Now I get:

Error 1 error C2036: 'UIScene *const ' : unknown size

##### Share on other sites
class SceneManager { private: vector<UIScene> m_Scenes; //you have to have a pointer here too public: void LoadInitialScreen(string Path); void AddScreen(UIScene* Screen); }; 

Did you change the
vector<UIScene> m_Scenes;

to

vector<UIScene*> m_Scenes;

And if you did, have you included the UIScene.h in your cpp file?

##### Share on other sites
Your class makes no sense. Each UIScene contains a discrete SceneManager. The SceneManager has a list of UIScenes. How can you construct an instance of this class?

One of these will need to change to some form of reference to make sense. For example, the UIScene might store a (smart) pointer to the SceneManager, or vice versa. Or see if you can factor out the code that requires knowledge of the "parent" relationship.

##### Share on other sites

class SceneManager { private: vector<UIScene> m_Scenes; //you have to have a pointer here too public: void LoadInitialScreen(string Path); void AddScreen(UIScene* Screen); }; 

Did you change the
vector<UIScene> m_Scenes;

to

vector<UIScene*> m_Scenes;

And if you did, have you included the UIScene.h in your cpp file?

I didn't change it because I thought I didn't have to. I mean, I'm using indirection to access the instance in my method. But I'll try to change it...

##### Share on other sites

Your class makes no sense. Each UIScene contains a discrete SceneManager. The SceneManager has a list of UIScenes. How can you construct an instance of this class?

One of these will need to change to some form of reference to make sense. For example, the UIScene might store a (smart) pointer to the SceneManager, or vice versa. Or see if you can factor out the code that requires knowledge of the "parent" relationship.

It makes perfect sense. All UIScene instances are being initialized from Lua, and with the same SceneManager instance (which is globally available to Lua through luabind).

And changing vector<UIScene> to vector<UIScene*> made my code compile, finally. However, I'm not sure if it is actually possible to pass a pointer to an object from Lua. I'll have to see about that..

##### Share on other sites
The part with the
vector<UIScene*>
is the same thing like before. The Compiler did not know the size of UIScene so i could not allocate the memory.

With the issue about passing a pointer through the script. I think there is a possibility but a dirty one. I did not test it so i might not work.

You could interpret your pointer (depending on the system architecture (32 bit or 64 bit)) as an Integer or something. It should be easy to give that to a script.

//Let's say you have a pointer of a class called CToScript with the name m_toScript //I do not know if it works unsigned int* m_pointerToPass= (unsigned int*) &m_ToScript; //It would be easier to use a union or sth. like that. 

##### Share on other sites

And changing vector<UIScene> to vector<UIScene*> made my code compile, finally. However, I'm not sure if it is actually possible to pass a pointer to an object from Lua. I'll have to see about that..

It's been a while but I am pretty sure this is a bad idea. However, you could allocate your objects in a data structure like a map<> and pass the key in instead. Would be a much safer design.

##### Share on other sites

All UIScene instances are being initialized from Lua, and with the same SceneManager instance (which is globally available to Lua through luabind).[/quote]
Your class takes the scene manager by value. All UIScene instances have copies of the SceneManager at the time they were created. I imagine this is not what you want.

• 18
• 11
• 16
• 9
• 49
• ### Forum Statistics

• Total Topics
631397
• Total Posts
2999783
×