For example, I develop several custom widgets, for each I create a separate .h and .cpp file. In these files (classes) I need the headers #include <QtWidgets> or #include <QLabel> . But if I connect them inside my .h file, and then connect my class and <QtWidgets> also in main.cpp , then it turns out I connect one file twice, but this is not very good. If I do not connect anything in my classes, then if I forget to connect a header to main.cpp , then nothing will work.
Where and how to connect them correctly? How do they usually do it?
3 answers
For this there is #pragma once :
// header.h #pragma once ... and include gruards :
// header.h #ifndef __HEADER_H__ #define __HEADER_H__ ... #endif // __HEADER_H__ which will not allow the header to be used twice and cause a compilation error. And to repeat #include directives is sometimes better for:
- visibility
- modularity
because if you remove a custom widget with a bunch of useful headers from main.cpp , then the compiler will sprinkle swearing about something that is not related to that widget at all. Imagine such a fun refactoring?
- oneAnother thing to add is a small rule: the file should contain only those header files whose elements are used in this file. In other words, if
QWidgetneeded in the.hcustom widget, and to display the logs of this custom class you need, say,qDebugThat the inclusion ofQtGlobalshould be in the.cppfile,QWidget- in the.hfile - user1056837 - As for
include guards, will it work correctly if the custom widget connects for the first time (#include<customWidget>) and then the header (#include<QtWidgets>) that already contains the custom widget (inside<QtWidgets>)? - Nik - one@Nik, this leads to untidiness in the code. In addition, it becomes easier to move files in the case of the notorious refactoring. Also, the structure becomes more transparent - you can see which tools are used to solve a specific applied task (class implementation), and the headers in the class hierarchy also become cleaner. - user1056837
- oneThe @Nik inclusion condition is inside the
<QtWidgets>, not outside. Therefore, it does not matter where you connect it. The second, third, etc. times the body of the included file will not really be included, because it will lead to a compilation error otherwise. - 伪位蔚蠂慰位蠀蟿 - one@Nik You shouldn鈥檛 be concerned about this exactly) QtWidgets developers have also provided for this - free_ze
It is necessary to connect header files where they are really needed. Quite often it is enough (for example, if only pointers or type references are used) in your header file, place only the preliminary declaration of the type used through:
class Sometype; And #include "Sometype.h" already done in the *.cpp implementation file, where you really need to know everything about the Sometype type. Such an approach can significantly save time when assembling a project.
- That is, for example, in
customLabel.hI write just aclass QLabel;, and incustomLabel.cppI already connect#include <QLabel>, do I understand correctly? And what is the use of such a record? - Nik - 2
- Now I tried to use a preliminary declaration - I declared it in the .h
class QWidgetfile, and I made it in .cpp, but the compiler throws out errors in the style "base class is not defined", that is, as if the class is not defined. - Nik - @Nik need to look at how the
QWidgetused in the .h file. - 伪位蔚蠂慰位蠀蟿 - one@Nik for inheritance you need to know the size, that is, you need a complete definition of the class. - 伪位蔚蠂慰位蠀蟿
Most header files include define and ifndef conditions in order to avoid such situations. QtCreator automatically creates these macros if you created them from it.
Do not worry about this if you have these macros.
As I know, all this is already in standard Qt files.