so this obviously isn't the real error, but i have no idea what the actual error is because the symptom is so vague. I'll just include the files here and you guys tell me where and what you think it might be causing the undeclared identifier error.
system.h(66): error C2065: 'EntityManager' : undeclared identifier
system.h
/*******************************************************************************
filename: System.h
Author:
Date: November 13, 2010
********************************************************************************/
#ifndef SYSTEM_H
#define SYSTEM_H
#include <string>
#include <memory>
//The interfaces for the framework elements.
#include "I_OS.h"
#include "I_Graphics.h"
//The derived interface elements tailored to the platform.
#include "Windows_module.h"
#include "D3D11_module.h"
#include "EntityManager.h"
// ** AUTHOR NOTE ** temporary until ini file reading is implemented
#define FULL_SCREEN false
/*******************************************************************************
Purpose:
This will be the central object that is responsible for containing and
systematically initializing, updating per frame, and shutting down ALL the objects
responsible for the various internal workings of the framework. This will also
serve as the nexus for all external entities to retrieve data, interface with engine
elements, as well as interfacing between eachother.
********************************************************************************/
class System
{
public:
/* All framework elements and interfaces contain an Initialization context to be
created outside, filled out, and passed into the Initalize function. This is to
maintain polymorphic similar function declarations, while still having variable
parameters */
class InitializeContext
{
public:
HINSTANCE hinstance;
};
System();
~System();
bool Initialize(InitializeContext &);
void Run();
void Shutdown();
public:
//pointer declarations of interface types for each framework element
std::shared_ptr<I_OS> m_os;
std::shared_ptr<I_Graphics> m_graphics;
std::shared_ptr<EntityManager> m_EntityManager;
};
/* This will be the global pointer that all entities will use to access the
public interface pointers to the entire framework.
** AUTHOR NOTE ** : all entities should refer to the interfaces, and non platform
specific elements to maintain crossplatform compatibility, (if it can be avoided)*/
extern std::shared_ptr<System> g_System;
#endif
EntityManager.h
/*******************************************************************************
filename: EntityManager.h
Author:
Date: October 27, 2011
********************************************************************************/
#ifndef ENTITY_MANAGER_H
#define ENTITY_MANAGER_H
#include <vector>
#include <map>
#include <fstream>
#include <memory>
#include "EntityBase.h"
#include "EntityList.h"
/*******************************************************************************
Purpose:
This wil be the object responsible for managing and updating all the various Entities
currently rendered in a scene. It reads from a scene file and dynamically creates instances
of the objects listed to be stored in a vector. these objects can be accessed individually
by either index or unique string identifier, or you can obtain a vector that contains
objects of the same class type.
********************************************************************************/
class EntityManager
{
public:
bool Initialize();
bool Frame();
void Shutdown();
private:
BaseFactory m_factory;
std::vector <std::shared_ptr<BaseEntity> > m_EntityList;
std::map<std::string, std::shared_ptr<BaseEntity> > m_EntityByNameList;
std::map<std::string, std::vector<std::shared_ptr<BaseEntity> > > m_EntityByClassList;
};
#endif
So is there anything wrong with these to be causing EntityManager to be undeclared? It's the only error in the output. Think you need anymore files and i'll include them.
This is normally caused by the circular inclusion of header files. In your case, it looks like either EntityBase.h or EntityList.h includes System.h. The simplest way to solve this is to remove #include "EntityManager.h" from System.h and forward declaring class EntityManager; in system.h. Note that you need to do #include "EntityManager.h" in system.cpp.
Related
This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 2 years ago.
So, I know that there are many questions on stack overflow out there that are trying to handle circular dependencies. But none of those could really answer my question, if it is possible to have two classes know each other, and, more importantly, access information from each other. So, basically, I have read that you could use forward decleration, but with forward decleration, I couldn't access any fields. Maybe I should also add that I am really new to C++.But enough talking, let's get to an example:
Let's say we have a class called Scene and a class called EntityBase, which are defined as following:
EntityBase.h
#pragma once
#include <string>
#include "Scene.h"
class EntityBase
{
public:
std::string entityId;
Scene scene;
EntityBase(std::string entityId);
/*
This method will be called when this object is added to the scene
*/
void onAddedToScene(Scene* scene);
/*
This method will be called when this object is removed from the scene
*/
void onRemovedFromScene(Scene* scene);
};
Scene.h
#pragma once
#include <vector>
#include <string>
#include "EntityBase.h"
class Scene
{
public:
std::vector<EntityBase> entities;
std::string name;
Scene(std::string name);
void addToScene(EntityBase& entityBase);
};
The question arises,
How can I print out the name of Scene(and use every method of Scene) while EntityBase can fully access Scene too?
So, I'd really appreciate if you'd tell how to do this, because I will probably need to access every field and/or method later.
Since the C++17 standard you don't need the full EntityBase class definition for the Scene class, only a forward declaration:
#pragma once
#include <vector>
#include <string>
class EntityBase; // Forward declaration
class Scene
{
public:
std::vector<EntityBase> entities;
std::string name;
Scene(std::string name);
void addToScene(EntityBase& entityBase);
};
You of course need to include EntityBase.h anywhere where the entities vector is used, most notable in the Scene.cpp source file.
Since EntityBase is using an actual instance of Scene you can't do the same with that class and the EntityBase.h header file. Here you must include the Scene.h header file.
If you build targeting an older C++ standard (C++14 or earlier) then you must have the full definition of the EntityBase class for the vector.
As a possible workaround either make entities a vector of pointers to EntityBase; Or make EntityBase::scene a pointer and use forward declaration in the EntityBase.h header file instead. Or a combination of both.
I'm using wxWidgets with CodeBlocks, and I'm trying to instantiate a class called FileManager as an attribute of the Frame for wxWidgets, and pass the wxFrame parent to the constructor of FileManager. The objective is to be able to able to refer to the wxFrame from within FileManager. I'm getting an error "FileManager does not name a type". Not sure what I'm doing wrong thanks
The project is called "MullSimple_CB" so the main frame class is "Mull_Simple_CBFrame" Here are the files.
So the main object is a wxFrame object of class MullSimple_CBFrame, defined inside MullSimple_CBMain. The class I want instantiated as a member of that class is FileManager
MullSimple_CBMain.h
#ifndef MULLSIMPLE_CBMAIN_H
#define MULLSIMPLE_CBMAIN_H
#include "non-wx/file_manager.h"
class MullSimple_CBFrame: public wxFrame
{
public:
MullSimple_CBFrame(wxWindow* parent,wxWindowID id = -1);
virtual ~MullSimple_CBFrame();
// ERROR ON THIS LINE:
// "'FileManager' does not name a type"
FileManager fileManager(MullSimple_CBFrame parentFrame);
private
DECLARE_EVENT_TABLE()
};
#endif // MULLSIMPLE_CBMAIN_H
MullSimple_CBMain.cpp
#include "wx_pch.h"
#include "MullSimple_CBMain.h"
#include <wx/msgdlg.h>
#include "non-wx/file_manager.h"
MullSimple_CBFrame::MullSimple_CBFrame(wxWindow* parent,wxWindowID id)
{
FileManager fileManager(this);
}
FileManager.h
#ifndef FILE_MANAGER_H_INCLUDED
#define FILE_MANAGER_H_INCLUDED
#include "../MullSimple_CBMain.h"
class FileManager
{
private:
MullSimple_CBFrame storeMainFrame;
public:
// constructor
FileManager(MullSimple_CBFrame mainFrame);
};
#endif // FILE_MANAGER_H_INCLUDED
FileManager.cpp
#include "file_manager.h"
#include "../MullSimple_CBMain.h"
FileManager::FileManager(MullSimple_CBFrame mainFrame): storeMainFrame(mainFrame))
{
}
Your file_manager.h file includes MullSimple_CBMain.h and the MullSimple_CBMain.h file includes your file_manager.h.
You end up with a never ending chain of includes... which never resolve.
Consider putting forward declarations into a single .h file and then have your .h files only include it as opposed to including the individual class.h files themselves. The only time you need to include the class.h files themselves is if you need the compiler to know about the full definition of the class as opposed to just knowing the class exists at all.
I'm having some troubles where a function isn't returning the right type, because a class isn't defined. I'm using a factory pattern.
The two error messages that I'm getting are:
'return': cannot convert from 'DLA *' to 'Layer *'
and:
'Layer': base class undefined (compiling source file src\Layer.cpp)
and this same error message is repeated for every file that includes Layer.h.
Here is what my class that inherits from Layer looks like (DLA.h):
#pragma once
#ifndef _DLA
#define _DLA
#include "ofMain.h"
#include "ofxGui.h"
#include "Layer.h"
class DLA: public Layer
{
public:
DLA();
void setup();
void update();
void draw();
private:
};
#endif
and here is my Layer class header (Layer.h):
#pragma once
#ifndef _LAYER
#define _LAYER
#include "ofMain.h"
#include "ofxGui.h"
#include "DLA.h"
enum SceneType
{
Scene_None,
Scene_Default,
Scene_DLA,
};
class Layer
{
public:
void setup();
void update();
void draw();
static Layer *CreateSimulation(SceneType Type);
private:
};
#endif
The function which is failing is this one, situated in Layer.cpp:
Layer *Layer::CreateSimulation(SceneType Type)
{
switch (Type)
{
case Scene_None:
default:
return nullptr;
case Scene_DLA:
return new DLA();
}
}
I've tried everything I could find on Stack Overflow that had similar issues to mine but I've seen some people recommend very subtle code indentation to fix this, so I'm really lost as to find where the problem is.
As they stand, your header files induce circular dependency, even though the #pragma once (and other) guards prevent any actual 'infinite recursion'. Let's look at the sequence of code, from the compiler's point-of-view, when compiling the Layer.cpp file (or any other '.cpp' source that has #include "Layer.h" in it).
The compiler encounters #include "Layer.h" (the first time it has done so - the guards won't be 'triggered'), so it duly replaces that line with the contents of the indicated header. In that content, it encounters #include "DLA.h" (we can ignore the other headers included in this discussion, assuming that they aren't relevant to the problem in hand). So, it then duly replaces that line with the contents of the DLA.h header, at which point it will come across this:
#include "Layer.h"
class DLA: public Layer
{
Now, here, when it replaces #include "Layer.h" with the header content, that content will be 'empty' (because of the guards, as it has already included that header once). Thus, when the public Layer code is encountered, it is an error, because that class has not yet been defined, or even declared as a class.
So, if you really insist on having the #include "DLA.h" line in Layer.h, then it must be placed after the definition of the Layer class.
However, a far better way would be to remove #include "DLA.h" from Layer.h, and only place it in source (.cpp) files that actually need it (like Layer.cpp). This would work well:
// Layer.cpp
#include "Layer.h"
#include "DLA.h" // At this point, references to the Layer class in DLA.h will be fine!
//...
Layer *Layer::CreateSimulation(SceneType Type)
{
switch (Type)
{
case Scene_None:
default:
return nullptr;
case Scene_DLA:
return new DLA();
}
}
Feel free to as k for any further clarification and/or explanation.
I have three classes.
first class:
#ifndef C_LINKED_LIST_H
#define C_LINKED_LIST_H
class CLinkedList {
private:
//removed code for brevity
public:
// removed code for brevity
};
#endif
second class:
#ifndef C_SSF_FOLDER_CONTAINER_H
#define C_SSF_FOLDER_CONTAINER_H
#include "C_SSF_Folder.h"
#include "CLinkedList.h"
class C_SSF_Folder_Container {
private:
// removed code for brevity
public:
int Add_Folder(C_SSF_Folder *_pcl_SSF_Folder);
C_SSF_Folder *Get_Folder(int _i_Index);
C_SSF_Folder *Get_Folder(char *_pch_Name);
//^-----errors
};
#endif C_SSF_FOLDER_CONTAINER_H
my third class
#ifndef C_SSF_FOLDER_H
#define C_SSF_FOLDER_H
#include <windows.h>
#include <fstream>
#include "C_SSF_Folder_Container.h"
using namespace std;
class C_SSF_Folder {
public:
private:
C_SSF_Folder_Container cl_SSFFC_Folder_Container;
public:
};
#endif
my third class C_SSF_Folder.
I am including "C_SSF_Folder_Container.h"
and declaring a C_SSF_Folder_Container container.
Before declaring the variable it compiles fine. After I declare it
I get syntax errors in my C_SSF_Folder_Container
Severity Code Description Project File Line Suppression State
Error C2061 syntax error: identifier 'C_SSF_Folder' CSSFileSystem\projects\cssfilesystem\cssfilesystem\c_ssf_folder_container.h 16
Error C2061 syntax error: identifier 'C_SSF_Folder' CSSFileSystem \projects\cssfilesystem\cssfilesystem\c_ssf_folder_container.h 19
As I myself look into it I think there is a problem because my C_SSF_Folder is including C_SSF_Folder_Container.
and C_SSF_Folder_Container is including C_SSF_Folder
but the defines should take care of it? Other than that I have no clue what's the problem.
Everything is typed correctly.
You've got a circular #include -- C_SSF_Folder_Container.h #includes C_SSF_Folder.h and C_SSF_Folder.h #includes C_SSF_Folder_Container.h.
This would cause an infinite regress (and a compiler crash) except that you've got the #ifndef/#define guards at the top of your files (as you should); and because of them, instead what you get is that one of those two .h files can't see the other one, and that's why you get those errors.
The only way to fix the problem is to break the circle by deleting one of the two #includes that comprise it. I suggest deleting the #include "C_SSF_Folder.h" from C_SSF_Folder_Container.h and using a forward declaration (e.g. class C_SSF_Folder; instead.
C_SSF_Folder.h and C_SSD_Folder_Container.h are including each other(Circular Dependency).
When the compiler compiles C_SSF_Folder_Container object, it needs to create a C_SSF_Folder object as its field, however, the compiler needs to know the size of C_SSF_Folder object, so it reaches C_SSF_Folder object and tries to construct it. Here is the problem, when the compiler is constructing C_SSF_Folder object, the object has a C_SSF_Folder_Container object as its field, which is a typical chicken and egg question, both files depends on each other in order to compile.
So the correct way to do it is to use a forward declaration to break the circular dependency(including each other).
In your C_SSF_Folder.h, make a forward declaration of C_SSF_Folder_Container.
#include <windows.h>
#include <fstream>
using namespace std;
class C_SSF_Folder_Container;
class C_SSF_Folder {
public:
private:
C_SSF_Folder_Container cl_SSFFC_Folder_Container;
public:
};
#endif
Finally, include C_SSF_Folder_Container.h in your C_SSF_Folder.cpp.
You can also learn more in the following links:
Circular Dependency (Wiki):
https://en.wikipedia.org/wiki/Circular_dependency
Forward Declaration by Scott Langham
What are forward declarations in C++?
I wanted to run the game by testing the spawner. I thought that I had properly declared the Spawner class by calling its header file in SceneGame.hpp
When I wanted to use the Spawner* as a vector variable, I thought there would be no compiler errors, but I was wrong.
The source of the error comes from declaring the variable vector spawner_list
Relevant files:
Spawner.hpp
#pragma once
#include <SFML\Graphics.hpp>
#include "weapon.hpp"
#include "movement.hpp"
// forward declare
class EnemyTemplate;
/*
Spawner will create enemies and/or power ups
For spawning enemies, they will recieve one weapon and one movement type
for powerups, only one will spawn and the spawner would disappear afterwards
The spawner will create entities through the following:
Spawn gap: the amount of time to wait between making enemies, in frame ticks
Spawn limit: the amount of enemies to make before being removed
*/
class Spawner{
private:
int spawnGapTime;
int spawnGapSet;
// If you plan to spawn finite enemies, then use constructor
int spawnLimit = -1;
EnemyTemplate* enemyData;
Weapon* givenWeapon;
Movement* givenMovement;
int ticks;
public:
Spawner(Weapon*, Movement*, EnemyTemplate*, std::vector <int>);
void update();
void spawn_enemy();
void spawn_count();
~Spawner(){
delete givenWeapon;
delete givenMovement;
delete enemyData;
};
};
SceneGame.hpp
#pragma once
#include <SFML\Graphics.hpp>
#include "scene.hpp"
#include "game.hpp"
#include "entity.hpp"
#include "movement.hpp"
#include "weapon.hpp"
#include "player.hpp"
#include "collisionGrid.hpp"
#include "spawner.hpp"
// forward declare
class BulletTemplate;
class SceneGame : public Scene{
private:
// skipping some code
std::vector <Spawner*> spawner_list; // The source of the error
public:
SceneGame(Game* game);
// skipping some code
};
Is there any way I can fix this undeclared identifier problem without having to forward declare Spawner?
C2065: 'class' undeclared identifier
If that is the literal text of the error message, you're compiling as C, not as C++.
If it isn't the literal text of the error message, you should have posted the literal text of the error message.