C++ Error: "pointer to incomplete class type is not allowed"

I was working on the first Live Training Tanks vs. Zombies tutorial when I got an error from my TankSprite pointer saying: “pointer to incomplete class type is not allowed”. I don’t know what this means and what is causing it. I was following the videos as closely as I could and only changing code that was required for 4.17, but this error appeared and it hasn’t gone away. Any answers, help and/or ideas would be greatly appreciated.


Visual Studio underlined in red TankSprite in the line: TankSprite->SetupAttachment(TankDirection); of my Tank.cpp file.

Here is my code for the Tank.cpp file:

// Fill out your copyright notice in the Description page of Project Settings.

#include "Tank.h"

// Sets default values
ATank::ATank()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	
	if (!RootComponent)
	{
		RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("TankBase")); 
	}

	TankDirection = CreateDefaultSubobject<UArrowComponent>(TEXT("TankDirection"));
	TankDirection->SetupAttachment(RootComponent);

	TankSprite = CreateDefaultSubobject<UPaperSpriteComponent>(TEXT("TankSprite"));
	TankSprite->SetupAttachment(TankDirection);
}

// Called when the game starts or when spawned
void ATank::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void ATank::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void ATank::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

}

And here is my code for the Tank.h file:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "Components/ArrowComponent.h"
#include "Tank.generated.h"

UCLASS()
class TANKS_API ATank : public APawn
{
	GENERATED_BODY()

public:
	// Sets default values for this pawn's properties
	ATank();

protected:
	ATank();
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

private:
	// Helpful debug tool - which way is the tank facing?
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Tank", meta = (AllowPrivateAccess = "true"))
	UArrowComponent* TankDirection;

	// Sprite for the tank body.
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Tank", meta = (AllowPrivateAccess = "true"))
	class UPaperSpriteComponent* TankSprite;
};

Just change:

class UPaperSpriteComponent* TankSprite;

To

UPaperSpriteComponent* TankSprite;

Your header is causing all this trouble because it thinks that your TankSprite is an undefined class.

Also, because of updates to Unreal, lots of content was moved to plugins. You’ll need to add Paper2D to your list of module dependencies in your build.cs.

 PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "Paper2D" });

After that, you can properly #include “PaperSpriteComponent.h” in your header. When you look up a class on the Unreal documentation for C++, if there’s a Module at the bottom, this seems to be what you add to your build.cs module dependencies to properly include it.

Your header file is not a problem, If you do forward deceleration of classes (which is thing you been doing and which is recommended in UE4 to avoid circular references of header files) you need to include header file in your *.cpp file that fully declare that class.

Otherwise compiler only see your forward class deceleration in your header file which is incomplete type which means compiler don’t know what to do with it as it does not know it’s stricture and size to properly generate machine code, so it needs information from header file that fully declare that type inside you cpp file.

In your case it does not matter if directly include or do forward deceleration as PaperSpriteComponent.h will never have any types from Tank.h to create circular reference. But still you can find lot of header in UE4 that does that and do forward declarations you may have incomplete type error, in that case you need to also include header file in cpp that declares fully that type, just a note for the future.

Without that decency you would have linker error. UBT need it to properly path lib directories.

Thank you for your help! I haven’t done much with C++ in Unreal so this is very helpful! I’ve came across this same problem, but with different pointers and variables and so far the solution has been adding their corresponding header files. Is #include a type of forward declaration? And what are circular references?

That worked! Thank you so much! I also added “Paper2D” to the list of PrivateDependencyModuleNames, I don’t know if that changed anything, but it is working now! Much appreciated!