A brief analysis of header file inclusion in VC++

  • 2020-04-02 01:36:35
  • OfStack

In some large projects, there may be dozens of base classes that inevitably reference each other (not inheritance, but composition). So you have to declare to each other. Okay, this is going to bring some confusion. If you don't handle it well, you'll make a mess. In my experience, here's how to handle it:

When coding, we generally try to avoid the include header file and declare class XXX instead. But sometimes you still have to use the Include header, so what separates the two?

It should be clear, but it doesn't seem to be mentioned in the book.

First of all:
We need to understand why declarations are used instead of header include: yes, to avoid unnecessary recompilation (when the header changes). Large projects, low speed machines, or basic classes change frequently (not a good design), compilation speed will be concerned, and, more importantly, the use of declarations to reduce coupling between code (classes), which is also a principle of object-oriented design.

Ii. General principles:
A. Include as little as possible in the header file, if you can simply declare class clsOld; Settle it. That's the best. Reduce unnecessary inclusions;
B. Also, include as few headers as possible in your implementation files.

Three: when can you simply declare class clsOld?
Simply put: you don't need to know the usage of the clsOld memory layout (except for static members), that is, if it's a pointer or a reference.
Such as:
ClsOld * m_pOld;       // pointer is 4 bytes long
ClsOld & test(clsOld *pOld) {return *pOld};
All OK.

Four: when can't you simply declare class clsOld and must include?
If three conditions are not satisfied:
Such as:
ClsOld m_Objold;   // do not know the occupied size, must be calculated by its specific declaration
The reason is simple: if you want to calculate sizeof(classNew), but you don't even know the sizeof clsOld, the compiler won't be able to do anything about it.

Special case:
Int test() {return clsOld::m_sInt; }
Static member calls, presumably you don't need to know the memory layout, but since you need to know that m_sInt belongs to the clsOld namespace, declaring class XXX is obviously not enough, so you must include the header file.

To sum up, I have the following Suggestions:
1:
If there are classes with common dependencies (which must include), such as A and B, which both depend on D, they can be put together, and then the users of the "D" class can only care about the related types exposed by the class, and the types used internally can be left alone (do not need to include D). This gives you a class that is better for the caller (no need to look up the code to see if you need to include other header files).

2: If class A depends on D, class B does not depend on D, you can separate them into two header files. The respective Include. This prevents unnecessary recompilation when D changes.

3: Try to call other classes with Pointers or references in your class so that you can declare only class XXX. And this also accords with the optimal use of resources, more conducive to the use of polymorphism.

-------------------------------
Why add "class CViewerView;" before the class CMainFrame when you are using the include file? Such as code? How about replacing it with an include file? Many Visual C++ books sidestep these issues, but it's actually an important one. If we don't understand the above code, we are likely to struggle with the inability to compile. These problems are based on the fact that when we design our programs in standard C/C++, it is a rule that two code files cannot be included with each other, and that multiple inclusion can lead to duplicate definition errors. In order to solve this problem, use Visual c + + # pragma once to notify the compiler to generate the contains (open) the only once, that is to say, after the first # include new compiler to generate when not to contain the include files (open) and read, and so we see in a wizard to create all the classes with # pragma header files from the once statement won't feel strange. However, it was this statement that caused the compiler to fail to recognize the referenced class correctly after the second #include. Therefore, we also need to add statements like class CViewerView when we include each other to inform the compiler that this class is an actual call


Related articles: