Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manage #include of header?

This is probably answered tonnes of times, but I can't seem to find the right post that talks about this issue.

Let us suppose we have classes A, B, and C that are containers of each other. This would entail that they'd have to include each other's header files. But when I do that in Visual Studio 2010, I get the error that reads "too many include files : depth = 1024".

In Java, I can have classes that import each other, but it appears the same cannot be done with C++ (why don't the compilers deal with that, really).

Anyhow, how do I get this to work?

like image 770
Some Newbie Avatar asked Jan 19 '26 12:01

Some Newbie


1 Answers

To avoid circular references you may "wrap" each include file into the preprocessor #ifdef's.

File A.h:

#ifndef SOMEREALLYUNIQUEIDFileAincluded
#define SOMEREALLYUNIQUEIDFileAincluded

#include "B.h"

class B;

/// Here you can use pointers to B
class A
{
  // something about B*
};

#endif // SOMEREALLYUNIQUEIDFileAincluded

File B.h:

#ifndef SOMEREALLYUNIQUEIDFileBincluded
#define SOMEREALLYUNIQUEIDFileBincluded

#include "A.h"

class A;

/// Here you can use pointer to A
class B
{
  // something about A*
};

#endif // SOMEREALLYUNIQUEIDFileBincluded

The #ifdef's are called the "include guards"

For modern compilers instead of writing "ifdefs" you can only write

#pragma once

at the beginning of each file.

EDIT:

Then you mught use all of the headers in C.cpp:

#include "A.h"

#include "B.h"

void test() {}

Test it with "gcc -c C.cpp" (compilation only).

EDIT2:

Some kind of a sample. A scene with renderable objects.

File Scene.h:

#ifndef SceneHIncluded
#define SceneHIncluded

class SceneObject;

class Scene {
public:
   void Add(SceneObject* Obj);
   void Render();
private:
   std::vector<SceneObject*> Objects;
};

#endif // SceneHIncluded

File Scene.cpp:

#include "Scene.h"
#include "SceneObject.h"

void Scene::Add() { this->Objects.pusj_back(Obj); Obj->SceneRef = this; }

void Scene::Render() {
   for(size_t j = 0 ; j < Objects.size() ; j++) { Objects[j]->Render(); }
}

File SceneObject.h:

#ifndef SceneObjHIncluded
#define SceneObjHIncluded

class Scene;

class SceneObject {
public:
   /// This is not the sample of "good" OOP, I do not suppose that
   /// SceneObject needs this reference to the scene
   Scene* SceneRef;
public:
   // No implementation here
   virtual void Render() = 0;
 };

#endif // SceneObjHIncluded

The implementation of the SceneObject might be some mesh with transformation, i.e.

 class Mesh: public SceneObject {...}

in the Mesh.h and Mesh.cpp files.

like image 59
Viktor Latypov Avatar answered Jan 22 '26 06:01

Viktor Latypov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!