Forward Declaration in C++ (Unreal Engine)
In C++ code inside Unreal Engine and others, anytime there is being used an extra type such as component, there's need to attach the type definition. This is done by
#include "ReferredSource.h" is included in any header
.h file, the preprocessor takes all of the content of the included header file, strips out useless parts such as comments, and then pastes all of the contents of that header file into the header file within which is included. By that way, the header file gets bigger as it contains also all the content of the included header files. As the best practice is to keep header files as small as possible, we only want to include things when they are used. To do so, we can use forward declaration.
Let's say, we need to define
UCapsuleComponent component within a header file.
UCapsuleComponent is not native part of the
Pawn class, there would be need to include the
USceneComponent type into the class by including
#include "Components/SceneComponent.h" into the header file.
If we would not make it, we would get an compilation error
error C2039: 'CapsuleComp': is not a member of .... However by including
#include "Components/SceneComponent.h" into our header file, we would place all the content of
"Components/SceneComponent.h" into our
Pawn class as well. This gets really crazy especially when we chain including into multiple classes - the size of any next class grows drastically.
At visualization above, supposing there is used
#include "childComponent.h" on each:
- We could continue further in such way, I guess you got it.
New, let's say we need to create yet another class that will use a type defined in
MyClass.h. By including
#include "MyClass.h" within our
yetAnotherClass.h, we would place a reference with this
#include not only at
MyClass.h, but also to
Capsule.h as the
MyClass.h includes these
classes. As a resul, we would get an analogy of
As you probably know, part of each
.cpp file (even right on the first place), is an
#include file referreing to the header
.h file of the
.cpp file. That means, that header
.h file is included within the
.cpp file, not the opposite. And, there is verz important to get understand following:
.h header file does not need to know the implementation details of specified class
.h header file does not need to know the implementation details of specified class such as
UCapsuleComponent from our example. Basically, header file really does care of how the functions of
UCapsuleComponent class are defined or how big the capsule component class is. Simply, a capsule component pointer
UCapsuleComponent* is the same size as amy other pointer - it's just an address.
That's why we can use the
forward declaration. Forward declaration is processed simply by adding the
class keyword before the unknown type (
UCapsuleComponent in our case), see:
class UCapsuleComponent* CapsuleCompt;
class keyword, there is an information for the compiler, that the
UCapsuleComponent is a type. Without that, the compiler does not recognizes the specified variable as the type (as there is not included the type definition), and thus throws an IntelliSense error.
Anyway, as the preprocessor does not throw an IntelliSense error after adding the
class keyword, it's still an incomplete type as it does not reffer to any type specification - we still need to specify that type. This is being done in the
Once we add
#include "Components/SceneComponent.h" into the
.cpp file, the
.cpp file has all information it needs, as it has included own
.h file as well (so defined variables meet their definition here).
Same example as above, only with a forward declaring - As of we do not have
#include "Base.h" anymore in our
"MyClass.h" file (as it's in
MyClass.cpp now), when we place
#include "MyClass.h" into our new
yetAnotherClass.cpp file (we still use forward declaring to allow to include our
yetAnotherClass.h anywhere in the future), we get an analogy of the
MyExtraClass.cpp file that contain only declaration of a type that we really need.
Remember when defining a C++ code:
- Include only what you use in
- Include as little as possible in
- There's no need the header to declare a pointer
- Header is necessary:
- to construct an object
- to access members (functions and variables)
#pragma oncein header files protects from