Error: Incomplete type is not allowed

Hi,

I recently tried porting my blueprints to C++ and I came across problem quite quickly. If have the following code:

#include "Unreal_Space.h"
#include "CTargetManager.h"
#include "CSpaceObject.h"




void ACSpaceObject::BeginPlay()
{
	Super::BeginPlay();
	CTargetManager xx;
	

}

With the corresponding .h file:

class CTargetManager;
#pragma once

#include "GameFramework/Pawn.h"
#include "CSpaceObject.generated.h"


/**
 * 
 */
UCLASS()
class UNREAL_SPACE_API ACSpaceObject : public APawn
{
	GENERATED_BODY()
	virtual void BeginPlay() override;

private:
	CTargetManager* targetManager;
	
public:

	
	
	
};

When I try to compile this I get the error ‘error C2079: ‘xx’ uses undefined class ‘CTargetManager’’
Visual Studio also tells me: ‘Error: Incomplete type is not allowed’
I am not sure what I am doing wrong. Can someone give me a hint?

I don’t know exactly but I’ve never seen a forward declaration at the very top of the file. You could try just putting “class” in front of the type when you use it, like: class CTargetManager* targetManager;

Your header file doesn’t include “CTargetManager.h” so it doesn’t know anything about a class called CTargetManager. To get around this make your class member targetManager's type class CTargetManager* instead of CTargetManager*. Alternatively you could just include “CTargetManager.h” in your header file, but I would avoid that if possible.

I’d also remove the forward declaration at the top of your header.

I changed the header file to:

#pragma once

#include "GameFramework/Pawn.h"
#include "CSpaceObject.generated.h"


/**
 * 
 */
UCLASS()
class UNREAL_SPACE_API ACSpaceObject : public APawn
{
	GENERATED_BODY()
	virtual void BeginPlay() override;

private:
	class CTargetManager*  targetManager;
};

Unfortunatly, the error persists. Did I misunderstand you somehow?

Hi,

You don’t make it clear where the error is coming from, but you need to include “CTargetManager.h” wherever you use targetManager, rather than where you define the pointer. So, for example, if your BeginPlay() function defined in your CSpaceObject.cpp file uses the targetManager member, you need to include it there:

// CSpaceObject.cpp
#include "MyPCH.h"
#include "CSpaceObject.h"
#include "CTargetManager.h" // need this...

void ACSpaceObject::BeginPlay()
{
    targetManager->DoSomething(); // ... or this won't compile
}

Also, a recommendation: avoid using ‘elaborated type specifiers’, i.e. putting ‘class’ (or ‘struct’ or ‘enum’) in front of variable definitions. Prefer to forward-declare them separately like you did before, just after your includes:

#pragma once

#include "GameFramework/Pawn.h"
#include "CSpaceObject.generated.h"

class CTargetManager;

UCLASS()
class UNREAL_SPACE_API ACSpaceObject : public APawn
{
       GENERATED_BODY()
       virtual void BeginPlay() override;

private:
       CTargetManager*  targetManager;
};

This avoids visual confusion of ‘class’ with ‘const’ as well as some confusing compile errors and possible compilation-order-dependent behaviour.

Steve

I switched the order of the #includes in the .cpp file. Now the file looks like this:

#include "Unreal_Space.h"
#include "CSpaceObject.h"
#include "CTargetManager.h"

void ACSpaceObject::BeginPlay()
{
	Super::BeginPlay();
	CTargetManager xx;
}

I still get the same error:
Error 1 error C2079: ‘xx’ uses undefined class ‘CTargetManager’ …\CSpaceObject.cpp 10 1 Unreal_Space

EDIT:
I found the error: I forgot the ‘A’ in front of the class name. Now it is working. Thank you very much for your time.