Is there any situation where "double linked headers" would be useful or necessary? (C ++)

I use the term "double link" because I don't know what the actual phrase is, or if there is one, but assuming you have two headers, head1.h and head2.h, with this content:

In head1.h:

#include"head2.h"
//do stuff

      

In head2.h:

#include"head1.h"
//do stuff

      

I imagine it as two mirrors facing each other, since this is not an endless loop, but some other form of getting infinity on a finite computer (but I digress). The point is, is there any situation where it would be useful or necessary to use this concept or a variation of this concept? (i.e. I assume goto can be used as a break from improvement).

+1


a source to share


4 answers


The fact that "cyclic switching" is not, it is not desirable. your goto won't help, because gotos are part of the program execution and #includes are interpreted in the preprocessing stage of compilation.

Typically, your header files are structured like

#ifndef FOO_H
#define FOO_H
... rest of the include file here
#endif

      



so that they don't try to define the same material twice.

If you try, this is what happens:

bash $ gcc crecursive.c
Included from bh.h: 1,

            from ah.h:1,  
            from bh.h:1,  
            from ah.h:1,   

      

     

... a lot of missing lines

            from ah.h:1,   
            from crecursive.c:2: ah.h:1:16: error: #include nested too deeply    

      

     

bash $

+3


a source


Usually, headers have preprocessor instructions to prevent just such a thing from infinite recursion:

#ifndef MY_FILE_H
#define MY_FILE_H

//do stuff

#endif

      



Even with this kind of protection, mutual inclusions are usually a bad idea.

+7


a source


The usual way to avoid this is with empty class declarations.

//head1.h

class Foo;

class Bar {
public:
   Bar(Foo* f) : foo(f) {}
private:
   Foo* foo;
};

// head2.h

class Bar;

class Foo {
public:
    void func(Bar* bar); 
};

      

When a header file creates many classes that need to be declared in front of each other, you usually end up with an include file like this.

//fwd.h

class Bar;
class Foo;

// head1.h

#include "fwd.h"

class Foo { ....

// head2.h

#include "fwd.h"

class Bar { ....

      

+1


a source


I imagine it as two placed mirrors opposing each other as it is not an endless loop

You are rendering incorrectly.;) Be aware that #include is nothing more than copy / paste, and this happens before your program is compiled. So you've created an infinite loop at compile time. The compiler reads head1.h which starts with C # include "head2.h". So it inserts head2.h and continues parsing that, but C # starts include "head1.h" so we have to include that, etc.

You usually have guards to prevent this from putting the compiler in an infinite loop.

The key is that this happens like normal text processing before compiling the program and of course before executing it, so it really isn't something you can use for anything constructive, unless you copy / paste infinite times of fun time.

0


a source







All Articles