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.
Related
I have this piece of code
#ifndef STATION_H
#define STATION_H
#include <vector>
#include "Dispenser.h"
#include "Cashier.h"
//class Cashier;
class Station
{
private:
int price;
int dispenser_count;
int cashier_count;
std::vector<Dispenser> dispensers;
std::vector<Cashier> cashiers;
public:
Station(int, int, int);
int GetPrice() const { return price; }
Dispenser *LookForUnoccupiedDispenser(int &id);
Dispenser *GetDispenserByID(int id);
Cashier *LookForUnoccupiedCashier();
};
#endif // STATION_H
When I have the class Cashier line commented, the compiler fails with a 'Cashier' was not declared in this scope error even though Cashier.h was included. Uncommenting it makes it possible to compile but I'm concerned that it shouldn't be happening.
Cashier.h
#ifndef CASHIER_H
#define CASHIER_H
#include "Station.h"
class Station;
class Cashier
{
private:
bool busy;
Station *at_station;
public:
Cashier(Station *employer);
bool IsBusy() const { return busy; }
};
#endif // CASHIER_H
How is it possible? It's clearly declared in the header file and as far as I know, #include does nothing more than pasting the content of a file into another one.
Thank you for the answers in advance!
Your station.h includes cachier.h. This is an example of cyclic dependency. Given that you only have a pointer to Station in Cachier I'd suggest removing the dependency of station.h and forward declare it.
An #include is literally nothing more than verbatim copy and paste of that file into the current compilation unit. The guards protect you from the effect of an infinite include cycle, but due to the guards one of the #includes does nothing, i.e. does NOT suck in the declaration (nor definition) of the respective class. This results in the error you get. In station.h the compiler has never seen any mention of the Cachier type when it sees the Station type.
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 have a trouble with my c++ code. I know there is much advices with error "expected class-name before ‘{’ token" but I still can't find where I have it. Here is my sources:
Postava.h
#include <exception>
#include <string>
using namespace std;
#ifndef __Postava_h__
#define __Postava_h__
#include "Barva.h"
#include "Pozice.h"
//#include "Budova.h"
//#include "HerniEngine.h"
#include "GrafickyObjekt.h"
class Budova;
class HerniEngine;
//class GrafickyObjekt;
class Postava;
struct Barva;
struct Pozice;
class Postava:public GrafickyObjekt{ //<----- Here is the error
private:
std::string m_jmeno;
int m_nosnost;
public:
Postava(std::string jmeno, int nosnost);
Budova* m_Budova;
HerniEngine* m_HerniEngine;
std::string vratJmeno();
int vratNosnost();
void vykresli();
};
#endif
GrafickyObjekt.h
#ifndef __GrafickyObjekt_h__
#define __GrafickyObjekt_h__
#include "HerniEngine.h"
#include "Pozice.h"
#include "Posun.h"
class HerniEngine;
class GrafickyObjekt;
class Scena;
struct Pozice;
struct Posun;
class HerniEngine;
class GrafickyObjekt {
protected:
Pozice m_pozice;
public:
HerniEngine* m_HerniEngine;
// kazdy potomek, tj. graf. obj. ma pozici
GrafickyObjekt(Pozice pozice);
// vsichni potomci ji musi implementovat
virtual void vykresli() = 0;
// tyto metody nejsou (ciste) virtualni, budou normalne zdedeny
// tim mam zaruceno, ze vsichni potomci je maji
void pohni(Posun posun);
void pohni(Pozice pozice);
};
#endif
Sorry for my english and for names of classes and names of variables, it's in czech.
Thanks a lot for every advice.
Same answer as in all similar questions asked before:
You created a circular include sequence
It is not obvious from what you posted so far (since you haven't posted all headers). But it is a safe bet that your other header files taken together must produce a circular include "path". More precisely, your GrafickyObjekt.h somehow indirectly includes Postava.h (through other header files that you haven't posted).
The include guards you used in your header files will "break" that cycle in some unpredictable or (better word) unforeseen way. In your case the include guards caused Postava.h to get physically included first, which is why it knows nothing about GrafickyObjekt even though it seems to explicitly include GrafickyObjekt.h. Hence the error.
Circular includes make no sense and achieve nothing. You have to stratify your headers by levels - from low level to high level - and make sure that higher-level headers include lower-level headers, but never the other way around.
Once you achieve that sort of order, you can proceed to resolving circular data dependencies by introducing forward class declarations. I see that you already tried to do that and ended up with a total catastrophic mess, where you basically forward-declare all classes in all headers. Get rid of that mess and start over, by fixing the include stratification first.
It seems that some of your previous includes are faulty.
#include "HerniEngine.h"
#include "Pozice.h"
#include "Posun.h"
I checked out a post similar to this but the linkage was different the issue was never resolved. The problem with mine is that for some reason the linker is expecting there to be a definition for the base class, but the base class is just a interface. Below is the error in it's entirety
c:\users\numerical25\desktop\intro todirectx\godfiles\gxrendermanager\gxrendermanager\gxrendermanager\gxdx.h(2) : error C2504: 'GXRenderer' : base class undefined
Below is the code that shows how the headers link with one another
GXRenderManager.h
#ifndef GXRM
#define GXRM
#include <windows.h>
#include "GXRenderer.h"
#include "GXDX.h"
#include "GXGL.h"
enum GXDEVICE {
DIRECTX,
OPENGL
};
class GXRenderManager {
public:
static int Ignite(GXDEVICE);
private:
static GXRenderer *renderDevice;
};
#endif
at the top of GxRenderManager, there is GXRenderer , windows, GXDX, GXGL headers. I am assuming by including them all in this document. they all link to one another as if they were all in the same document. correct me if I am wrong cause that's how a view headers. Moving on...
GXRenderer.h
class GXRenderer {
public:
virtual void Render() = 0;
virtual void StartUp() = 0;
};
GXGL.h
class GXGL: public GXRenderer {
public:
void Render();
void StartUp();
};
GXDX.h
class GXDX: public GXRenderer {
public:
void Render();
void StartUp();
};
GXGL.cpp and GXDX.cpp respectively
#include "GXGL.h"
void GXGL::Render()
{
}
void GXGL::StartUp()
{
}
//...Next document
#include "GXDX.h"
void GXDX::Render()
{
}
void GXDX::StartUp()
{
}
Not sure whats going on. I think its how I am linking the documents, I am not sure.
The problem is You need to have #include "GXRenderer.h" at the top of both: GXGL.h and also GXDX.h.
The base type must be defined not just declared before defining a derived type.
By the way, the error is a compiling error not linking error.
Edit: About your class type redefinition:
at the top of every header file you should have #pragma once.
The #pragma once directive specifies that the file will be included at most once by the compiler in a build.
You included them all into GXRenderManager.h, meaning that GXRenderManager.h is OK.
But you forgot to include them all into GXGL.cpp and GXDX.cpp. In these .cpp files GXRenderer class is completely unknown.
There are at least two "schools" of #include strategies. One says that header file must include everything that is needed for its own compilation. That would mean that GXGL.h and GXDX.h must include GXRenderer.h. If you followed that strategy, your GXGL.cpp and GXDX.cpp would be OK as they are now.
Another "school" says that header files must not include each other at all, i.e. all inclusions must be done through .cpp files. At first sight one could guess that your GXGL.h and GXDX.h follow that strategy (since you are not including anything into them), but then your GXRenderManager.h looks completely different.
You need to decide which strategy you are trying to follow and follow it. I'd recommend the first one.
I got an error C2504: 'CView' : base class undefined
where CView is not directly my base class from which I am inheriting.
I am inherting mYClass from MScrollView, "for this matter any class which is not actual Base Class is what the point is to be noted down here"
but the error is the C2504. When I have included it in the header where this problem is arising, this problem is resolved.
#include "stdafx.h"
where stdafx.h has #include which contains all the basic class defined...hope this answer resolves everyone who are facing this issue.
My CGameStateLogo which inherit from CGameState:
CGameState.h
#pragma once
#include "GameMain.h"
#include "MyBitmap.h"
class CGameMain;
class CMyBitmap;
class CGameState
{
public:
CMyBitmap* pbmCurrent;
CGameMain* pGM;
int GameStateID;
virtual void MessageEnter () = 0;
virtual void MessageUpdate( int iKey ) = 0;
virtual void MessagePaint( HDC* pDC ) = 0;
void StateHandler ( int msg, HDC* pDC, int key );
public:
CGameState(void);
~CGameState(void);
};
After creating and finding, problem comes from here :
I've created 2 classes: CTest and CGameStateLogo
#pragma once
#include "GameState.h"
class CTest:CGameState
{
public:
CTest(void);
~CTest(void);
};
#pragma once
#include "GameState.h"
class CGameStateLogo:CGameState // Bug at this line
{
public:
CGameStateLogo(void);
~CGameStateLogo(void);
};
Do VS has problem in naming ?
Thanks for reading this :). Things go WEIRD, I'll update my question later. Sorry for wasting your time .
pGameStates.push_back( (CGameState*)gameLogo );
Since CGameStateLogo inherits publically from CGameState, the cast is unneccesary. Upcasts are implicit. Simply write
pGameStates.push_back( gameLogo );
instead.
This does probably not solve your compile troubles, though. As to that, you seem to be mixing up GameState.h and CGameState.h. If that's an actual error in your code, instead of just a copy/paste mistake while writing your question, it could cause this problem.
It could also be that there is some circular dependency problem in your headers. You write
#include "GameState.h"
which should define the GameState class, unless the file has already been included once, but the class definition has not yet been read. This could happen for example in this way:
Some .cpp file includes GameState.h.
GameState.h includes GameMain.h.
GameMain.h includes GameStateLogo.h.
GameStateLogo.h includes GameState.h, but this has already been included, so the include is ignored due to #pragma once.
Generally, such circular dependencies in header files are a thing to avoid.
CGameStateLogo.h is including GameState.h and not CGameState.h. Is it possible you have a file called GameState.h on the include path (and hence you wouldn't get an error about not being able to include GameState.h)?