Pointer to incomplete class type is not allowed

Your problem: You are just doing this awesome tutorial from Udemy, the Battery Collector series, following the docs or any other C++ tutorial in Unreal Engine 4. But on some point you get the error “Pointer to incomplete class type is not allowed”. Then please read the answer to understand the causes and how you can easily fix it (yes, this is the shortest answer to this problem, please make sure to read the links I used, because I just want a short version of the docs and in my opinion, they also miss some information that beginners need to know, also including Engine.h is not the best solution to fix your issue!)

Hey, first you have to read and understand all the new changes how Unreal includes his header files now.
tldr; many of these tutorials included an Engine.h file in the .h files of your class that gives you access to many classes, but Unreal changed to a Include What You Use (IWYU) model to make compiling times ridiculously fast, but now it’s up to you to include everything you are using (example below, again, please read the docs for further information)

You might ask now: “But where should I know what I need to include?” That’s easy.

  1. In Visual Studio you can select the Solution Explorer and search for your component. Make sure to click on the engine first, because that’s where all the code is. If you search for UBoxComponent.h you will see it under Engine/UE4/Source/Runtime/Engine/Classes/Components/BoxComponent.h. However, you just start at Runtime when including for some reasons I explain another day.

  2. You can go to the Unreal Engine API (make sure C++ API search is active) and just type in the class you need (for example: UBoxComponent). Usually, the first entry will direct you to the class and now all you need to do is looking at the bottom of the page and you can see the header you need to include in your class (in our example: Runtime/Engine/Classes/Components/BoxComponent.h).

  3. Visual Assist can actually search what you need to include, you can check out the free version and see if it works for ya (how: see answer from Nachtmahr below)

In most cases you also want to use Forward Declaration (tutorial made by Rama ofc ;P), that means in your .h file you use the class keyword and include the class you need in your .cpp file.

Alright, let’s check one example of a simple Pickup class that inherits from StaticMeshActor and has a BoxTrigger that is attached to the RootComponent (which ofc is the Static Mesh, because we inherit from StaticMeshActor).

Pickup.h

#pragma once

#include "CoreMinimal.h"
#include "Engine/StaticMeshActor.h"
#include "Pickup.generated.h"

class UBoxComponent;

UCLASS()
class CODETEST_API APickup : public AStaticMeshActor
{
	GENERATED_BODY()

public:	
	APickup(const class FObjectInitializer& ObjectInitializer);

	UPROPERTY()
	UBoxComponent* TriggerVolume;
	
};

Pickup.cpp

#include "Pickup.h"
#include "Classes/Components/BoxComponent.h"

// Sets default values
APickup::APickup(const FObjectInitializer& ObjectInitializer)
:Super(ObjectInitializer)
{
	RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("DefaultSceneComponent"));
	TriggerVolume = CreateDefaultSubobject<UBoxComponent>(TEXT("VolumeTrigger"));
	TriggerVolume->SetBoxExtent(FVector(32.f, 32.f, 32.f));
	TriggerVolume->SetupAttachment(RootComponent);
}

If you carefully read all this wall of text and your code is still not compiling, feel free to add a comment and I’ll take a look at it. If people think this was helpful and there are enough upvotes, I can make a troubleshooting or something! Cheers! <3

__

There is an exception to including Pre-Compiled-Header files though (famous example is using GetWorld()). You actually don’t need to include them, and your game will compile, but Intellisense and VAX will still display the error. You can leave these includes out to reduce compile times even more, but the impact to exclude files that are already in the pch seems to be very low. If you include them though, Intellisense/ VAX won’t complain and you can use auto-complete again.

Good Answer Up Voted =) just want to add three things.

In Visual Assist its very easy todo. Click and Hover over the class in your Code and a dropdown will appear with a option to include the needed .h file. Done. Just a small issue sometimes that it will include files with “” instead of “/” the compiler will tell you and its a quick fix. (There should be a Option for this but Im always forget to look it up xD)

Second thing I wanted to point out is in your XYZ.Build.cs its important to add the Module from where the .h file is coming from. Otherwise it will make you trouble. The Module Name can be found on the API Page at the very Bottom if you look it up there. Or look in the root folder of the .h file for the related Module .cpp file at the very bottom/top (usually) you find a Macro like this:

IMPLEMENT_MODULE(FClassNameOfTheModule, ActualNameYouWantForYourBuildCS)

The Module Name can vary from the Class name you might guess. For Example FBlueprintEditorModule but the Module name is actually Kismet. Its rare but something to remeber =)

And last one is once you added the Module to the XYZ.Build.cs you can shorten your include to be relative to the Module Hierarchy. If you add “Engine” you can simply use #include "Engine/World.h" instead of the full path.

Thank you, Thank You, Thank You, Thank You!!!

Thank you for a very detailed and technical explanation! It was obvious they changed how they include everything, but it never occurred to me that I could just search in the solution explorer. Thanks for tip!

I ran into the same issue as @Ninjin. While using GetWorld(), it compiles and runs in the editor, however when I try to build my application (iOS) it fails and gives me the same error that VS provides.

Following this post Can't use GetWorld pointer code complete - #22 by Brandon_Fuller - Talk - GameDev.tv
I added the following includes

#include “GameFramework/PlayerController.h”
#include “Engine/World.h”

And then I was able to build my app successfully.

How about smart pointer + forward declaration?

…If I add a smart pointer (e.g. std::unique_ptr) as a member in APickup, and forward declares CustomClass in Pickup.h and put the #include directive in Pickup.cpp, I get the compile error C2338 “can’t delete an incomplete type”. Any ideas on how to solve this without putting the #include in the header?

I suspect that the GENERATED_BODY() macro causes this.

(in my case CustomClass is a completely non-UE class, which is why I want to manage lifetime myself)

This helped me, I had no problems to compile, but the error message on VS2017 was annoying

TSubclassOf can solve your problem