About circular dependency & #includes in C++ - c++

I've read several questions here about circular dependencies when using #include in the header files of classes , so for example:
// sorry edited the example to be clear
File Car.h
#include "Wheel.h"
#include <vector>
class Car
{
std::vector<Wheel> wheels;
};
File Wheel.h
#include "Car.h"
class Wheel
{
Car* car;
};
A compile error happens due to the circular dependency occurring between the 2 classes. My question is why if I just used #include "Wheel.h" in the .cpp of class Car or #include "Car.h" in the .cpp of class Wheel, the problem is solved. Isn't it still a circular dependency?

//A.h
#include "B.h"
class A
{}
//////////////
//B.h
#include "A.h"
class B
{}
There is no circular dependency in the shown code. Neither class depends on the other. (The code won't compile however, due to syntax errors).
Circular include simply means that one header is not before the other despite having been included at the top. This is simply because both cannot be before the other at the same time. If the class defined in the header that was included first depends on the one that was included second, then there would be an error.
Update for the new example:
In this case, Car depends on the definition of Wheel and Wheel depends on the declaration of Car. Note that Wheel does not depend on the definition of Car. It does not need to know what kind of class Car is, only that it is a class.
My question is why if I just used #include "Wheel.h" in the .cpp of class Car or #include "Car.h" in the .cpp of class Wheel, the problem is solved.
This is not correct, this does not solve the problem. It might make the problem disappear, but the program will remain buggy.
The correct solution is to include the definition of Wheel before Car is defined, and declare Car before Wheel is defined. Like this:
class Car;
class Wheel
{
Car* car;
};
class Car
{
std::vector<Wheel> wheels;
};

Related

C++ forward declarations with multiple classes, derived class

Currently I have 3 classes, set up like this:
World.h
include "WorldObject.h"
class WorldObject;
class TextObject; // when this is added, compiles fine, but tobj is incomplete when accessed
//(world->tobj->function()). if #include "TextObject.h" is added, numerous errors occur within TextObject.h
class World {
public:
WorldObject* wobj; // works fine
TextObject* tobj; //trying to get this to be functional
};
WorldObject.h
#include "World.h"
class World;
class WorldObject {
public:
WorldObject(World* world){...} // works fine, world can be accessed from world objects
};
TextObject.h
#include "WorldObject.h"
#include "World.h"
class TextObject : WorldObject {
public:
TextObject(World* world) : WorldObject(w){...};
};
How can I use forward declaration so that tobj will be accessible from World.h, as obj is, with no errors? I am also using #pragma once at the beginning of each class. I have attempted to add "class World" to TextObject.h and "class TextObject" to World.h, but none of the seemingly standard procedures are working. Any suggestions?
#include <WorldObject.h> in your .cpp file rather than your header and you can access it from there.
Your header includes are causing circular dependencies, which you avoid through forward declarations.

class composition and header problems

Currently, I'm writing a project for fun and faced next problem.Let's suppose I'm creating class Bank and I want to define classes LoginController and Departure
class Bank{
class LoginController{
//some implemantation
}
class Departure{
//some departure
}
}
To avoid making huge declaration of Bank inside Bank.h I want to define them in separate files
//Bank.h
#include "LoginController.h"
#include "Departure"
class Bank{
class LoginController;
class Departure;
LoginController controller;
Departure departure;
...
}
//LoginController.h
class Bank; //forward declaration
class Bank::LoginController{
bool getAccess(Bank::Departure);
}
//Departure.h
//Departure depends on Bank class aswell
class Bank; //forward declartion
class Bank::Departure{...}
This code wont compile with huge stack trace.It can be solved with one big Bank.cpp and writing it all there, however, i don't want to make one huge file.
I assume this is a bad design problem, however, i'm still interested if it possible to implement this class as I wanted.Even if I define LoginController && Departure structure inside Bank i want separate cpp files for each class, however, header guard will close access to it after including it to one of cpp files.The best solution i can see is defining all in one header but not inside each other.
And one more question.Is it possible to define 1 header file with all includes like
#ifndef HeaderFile
#define HeaderFile
#include <iostream>
#include <memory>
....
#endif
From the previous question, i understand that this will open only for one file, therefore do we need to provide each file with needed headers. Including the same header to different files seems expensive.
You can put the #include directives inside the Bank class.
Bank.h
class Bank {
#include "LoginController.h"
#include "Departure.h"
// Bank implementation
}
LoginController.h
class LoginController {
// some implementation
}
Departure.h
class Departure {
// some implementation
}

Having linking classes issue? c++ I have no clue what is up

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++?

expected class-name before ‘{’ token 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"

Dealing with circular dependency on inheritance

I'm gonna go C++ über n00b on this one and ask how is the best way to deal with a circular dependency when you have inheritance.
The set is simple: Scene class extends Actor; Scene has a pointer to a vector of Actors; Actor has a pointer for (parent) Scene.
As for include files I got:
Scene.h:
#include <string>
#include <vector>
using namespace std;
#ifndef __Scene_h__
#define __Scene_h__
#include "Actor.h"
namespace myns
{
// class Actor;
class Scene;
}
namespace myns
{
class Scene: public myns::Actor
{
/* private class attributes... */
public:
/* public class attributes... */
std::vector<myns::Actor*> actors;
Scene(/* arguments */);
/* public class methods... */
};
}
#endif
Actor.h
#include <string>
#include <vector>
using namespace std;
#ifndef __Actor_h__
#define __Actor_h__
#include "Scene.h"
namespace myns
{
// class Scene;
class Actor;
}
namespace myns
{
class Actor
{
/* private class attributes... */
public:
/* public class attributes... */
myns::Scene* scene;
Actor();
Actor(/* arguments */);
/* public class methods... */
};
}
#endif
But this gives me alot of C2504 errors/base class undefined on Visual Studio 2010.
If I comment the Scene.h include on the Actor.h and uncomment the forward declaration of Scene on Actor.h it works, but then, in my app, if I want to include only the Actor.h on a particular piece of code, it will not work. How can I put this to work while maintaining the inclusion independence for Actor.h - including Actor.h without the need of previously manually including Scene.h?
What is wrong with my class definitions and how is the best way to deal with this circular dependency?
Shouldn't the #ifndef directives prevent this inclusion problem?
Thanks in advance.
but then, in my app, if I want to include only the Actor.h on a particular piece of code, it will not work
What you need to do is in the .cpp file where you need to use define the Actor class you must include both Actor.h and Scene.h. That way the forward declaration will be resolved and everything should work.
As an aside, you should move your #ifndef and #define right to the top of the file, before the includes. Also, having a using in a header file is bad practice because other files that include your header might not work properly. It should be ok to put it inside your namespace myns { ... } though.
Is a Scene really a type of Actor?
If it is, Actors probably shouldn't know about Scenes. Base classes shouldn't usually know about their derived classes.
Where is the Liskov Substitution Principle here? What action do you perform on an Actor that would be polymorphically performed differently by a Scene.
In any case, Scene derives from Actor so must include its base class. But in Actor.h if you really do need the Scene class it must be a forward declaration only.
In the compilation units (the .cpp files) you might include both headers if required.