1
votes

I try to stick to the principle of including headers in implementation files and not in .h files. But for qt projects I have to run most of my header files through moc which then complains about classes it doesn't know about. I use moc header.h -o header.moc.cpp and then link all cpp's and the .moc.cpp's together. Example:

header1.h and a cpp file to go with it where I include header1.h at the top

#ifndef __HEADER_1_H
#define __HEADER_1_H

class Baseclass { /* ... */ };

#endif

header2.h and a cpp file to go with it where I include header1.h and header2.h at the top

#ifndef __HEADER_2_H
#define __HEADER_2_H
//here is where I then have to #include "header1.h" because of moc

class Derived: public QObject, public Base { Q_OBJECT; /* ... */ };
#endif

Now the problem is when I have another class in another header and cpp file:

header3.h #ifndef __HEADER_3_H #define __HEADER_3_H

//I have to include header2.h because moc doesn't know about Derived.

class Other : public QWidget { Q_OBJECT; Derived* d };

Then in an implementation file I need to use Derived and Other, but when I include their headers I obviously get multiple definition errors. I can circumvent this by including only header3.h which will in turn include the other headers. I think this leads to very confusing code with unnecessarily included stuff and other invisibly included stuff (thus being error prone). How can I do this better?

1
If you get multiple definition error you obviously have an error in your header. Fix it. - user2672107
You have been tried to use #pragma once instead? - Evyatar
I suggest throwing your policy into the trash. I suggest you #include files in an #include to satisfy declarations. For example, if one of your methods returns std::string, then put #include <string> into your header file. - Thomas Matthews
@ThomasMatthews for the function declaration (even if the parameter is by value) you only need the forward declaration. - Zlatomir

1 Answers

3
votes

You have multiple definitions because probably you have some function definitions in the header files, so move those to the corresponding .cpp files.

Now about includes: You need the include (full type) for inheritance (not for moc):

#ifndef __HEADER_2_H
#define __HEADER_2_H
//here you need to include header1, because you inherit from that class 
//and this needs to see the whole object blueprint
//forward declaration is not enough.
#include <QObject>
#include "Baseclass.h" //or header1.h or whateven the file name is

class Derived: public QObject, public Baseclass { Q_OBJECT; /* ... */ };
#endif

You need full type for inheritance and for the Derived you can use forward declaration, because you only have a pointer:

//you need include for QWidget, because you inherit from it
#include <QWidget>
//and forward declaration for derived
Class Derived;

class Other : public QWidget { Q_OBJECT; Derived* d };

In the file other.cpp you'll need to include the "Derived.h" if you want to use functionality from Derived