8

I have a problem regarding multiple inclusion of header file in C++ code.

Say for example, I have three classes X, Y, Z. X and Y are derived from base class Z. And I want to create an instance of X in Y. The code will go like this.

class Z { …some code… };

class X: public Z { …some code… };  //here #include header of class Z added

class Y: public Z  //here #include header of class Z added as well as of X class
{
private:
   X* mX;    //instance of X 

   …some code…
};

So in this multiple definition of all methods of base class arises. How can I cope with this problem?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
boom
  • 5,856
  • 24
  • 61
  • 96
  • possible duplicate of [redefinition c++](http://stackoverflow.com/questions/2823330/redefinition-c) – R Samuel Klatchko May 14 '10 at 05:46
  • [JFTR](https://www.acronymfinder.com/JFTR.html): Your class `Y` contains a pointer to an `X`; it does _not_ contain an instance of an `X`. With pointers, it would be sufficient to have the (forward) declaration `class X;` in scope when you define `Y` — you don't need the internal details of the structure of `X` to be able to use a pointer. – Jonathan Leffler Jun 10 '19 at 14:35

4 Answers4

11

Using "include guards" (Wikipedia link)

#ifndef MYHEADER_H
#define MYHEADER_H

// header file contents go here...

#endif // MYHEADER_H

This is idiomatic code, easily recognizable by any seasoned C and C++ programmer. Change MYHEADER_H to something specific to you, for example if the header defines a class named CustomerAccount, you can call the guard CUSTOMERACCOUNT_H.


In your specific case, have a separate header/source file for each class. The header file for the Z class will have an include guard:

#ifndef Z_H
#define Z_H

// Code of Z class

#endif Z_H

Now, the headers of both X and Y can include z.h safely - it will only really be included once in a .cpp file that includes both x.h and y.h and no duplication will occur.

Always keep in mind that in C and C++ what's really gets compiled are the source (.c or .cpp) files, not the header files. The header files are just "copy-pasted" by the preprocessor into the sources files that include them.

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
3

You can also use #pragma once preprocessor directive in your header files. (There's no need to bother about #ifndef, #define, #endif).

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
santhosh
  • 375
  • 1
  • 8
  • 16
2

You use what are called include guards or header guards. They go something like this:

// within some_header.h
#ifndef SOME_HEADER_H
#define SOME_HEADER_H

// stuff goes here

#endif

Essentially, the first time around the macro hasn't been defined so everything inside is included. However, after the first time subsequent includes will have no effect.

The naming scheme, like all naming schemes, is completely arbitrary and up to you. I like to include the file name as a minimum, as I did above, in that fashion. I also include namespaces and project names in my real projects.

There are a couple of things to watch out for. You might be tempted to do things like this:

#define _SOME_HEADER_H__

To obfuscate it a bit. However, names that begin with an underscore followed by a capital letter, or contain double-underscores are reserved identifiers, and you cannot use them.

GManNickG
  • 494,350
  • 52
  • 494
  • 543
-1

Here the simple way to avoid multiple header inclusion in the project.

//MYCLASS.h
#ifndef _MYCLASS_H_
#define _MYCLASS_H_

class CMyClass
{
public:
    CMyClass();
}

#endif //_MYCLASS_H_
  • 1
    In C++, symbols starting with, or containing, a double underscore are reserved for the implementation to use. That means you should not create such symbols. One of the other answers already points this out. It really isn't clear what new information you are providing compared to the other answers, and you are providing an invalid example — that's not good. – Jonathan Leffler Jun 07 '19 at 14:24
  • Note that you should not, in general, create function, variable, tag or macro names that start with an underscore. Part of [C11 §7.1.3 Reserved identifiers](https://port70.net/~nsz/c/c11/n1570.html#7.1.3) says: — _All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use._ — _All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces._ See also [What does double underscore (`__const`) mean in C?](https://stackoverflow.com/a/1449301) – Jonathan Leffler Jun 10 '19 at 14:31
  • The rules in C++ are similar (but I don't have the reference prepackaged as I do for C), and more stringent as it rules out double-underscore anywhere. You see this notation used in system headers and the like. That's OK; system headers are part of 'the implementation' and must not use symbols reserved for the general programmer (you and me). They must used such reserved names, but you must not copy them. – Jonathan Leffler Jun 10 '19 at 14:39