Unable to define my own constructor for subclass of AHUD

I’m a C++ programmer by day, but I’m totally new to Unreal. I’m having trouble giving my class a constructor (since it already has one, provided eventually by the GENERATED_BODY macro). I’m using Unreal 4.7.2.

The other answers to this problem I’ve found (usually about Unreal 4.6 or earlier) pretty much state that the constructor simply needs to be defined in the source file but not in the header, while others say it does need to be added to the header. This doesn’t sound right to me, because following the macro definitions shows that a constructor does indeed already exist in the generated code.

Ultimately my goal is to locate a font to use. Is there an alternate solution if this is not the way to accomplish it?

Here is my error:

error C2084: function 'ATestHud::ATestHud(const FObjectInitializer &)' already has a body

Here is my class’s header file:

#pragma once

#include "GameFramework/HUD.h"
#include "TestHud.generated.h"

UCLASS()
class PONG_API ATestHud : public AHUD
{
	GENERATED_BODY()

	ATestHud::ATestHud(const FObjectInitializer& ObjectInitializer);

	int value = 0;

public:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HUD Properties")
	UFont* _font;

	void ReceiveDrawHUD(int32 SizeX, int32 SizeY) override;
};

Here’s the source:

#include "Pong.h"
#include "TestHud.h"
// The following might not be the best way to include some utility functions, but that's another issue...
#include "../../Intermediate/ProjectFiles/Utilities.h"

ATestHud::ATestHud(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	
}

void ATestHud::ReceiveDrawHUD(int32 SizeX, int32 SizeY)
{
	const int BufSize = 80;
	char buf[BufSize + 1];
	c99_snprintf(buf, BufSize, "SizeX: %d  SizeY: %d", SizeX, SizeY);
	FString size_string = FString(buf);
	FLinearColor TextColor = FColor::White;
	if (size_string.IsEmpty() == false)
	{
		const float TextScale = 1.0f;
		const bool bDontScale = false;
		DrawText(size_string, TextColor, 0, 0, _font, TextScale, bDontScale);
	}
}

Delete the Declaration and Definition of the given Constrcutor from Header and Source.

Add you own Constructor to the Header file, the same way you would it in normal C++.

Add the constructor in your cpp file as well. I just checked my code and i do it the same way.

Works like a charm (:

PS: Small piece of code, so you can compare:

Header:

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

#pragma once

#include "GameFramework/Actor.h"
#include "BaseWeaponClass.generated.h"

namespace EWeaponState
{
	enum Type
	{
		Idle,
		Firing,
		Reloading,
		Equipping,
	};
}

UCLASS()
class SMALLCOOPTD_API ABaseWeaponClass : public AActor
{
	GENERATED_BODY()

public:	
	/// Constructors ///

	ABaseWeaponClass();

	
};

    CPP File:
    
    // Fill out your copyright notice in the Description page of Project Settings.
    
    #include "SmallCoopTD.h"
    #include "BaseWeaponClass.h"
    #include "UnrealNetwork.h"
    
    // Sets default values
    ABaseWeaponClass::ABaseWeaponClass()
    {
     	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    	PrimaryActorTick.bCanEverTick = true;
    	
    	/** Init Weapon Mesh Component. Doesn't work as expected **/
    	WeaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(FName("Weapon Mesh"));
    	WeaponMesh->MeshComponentUpdateFlag = EMeshComponentUpdateFlag::OnlyTickPoseWhenRendered;
    	WeaponMesh->bChartDistanceFactor = false;
    	WeaponMesh->bReceivesDecals = false;
    	WeaponMesh->CastShadow = true;
    	WeaponMesh->SetOnlyOwnerSee(false);
    	WeaponMesh->SetOwnerNoSee(false);
    	WeaponMesh->SetCollisionObjectType(ECC_WorldDynamic);
    	WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
    	WeaponMesh->SetCollisionResponseToAllChannels(ECR_Ignore);
    
    	/** Sets Rootcomponent to our WeaponMesh **/
    	RootComponent = WeaponMesh;
    
    	/** Actor can replicate | Network Property **/
    	bReplicates = true;
    
    	/** Init State System **/
    	bIsFiring = false;
    	bWantsToFire = false;
    	bPlayingFireAnim = false;
    	bLoopedFireAnim = false;
    	bIsReloading = false;
    	bPendingReload = false;
    	bIsEquipped = false;
    	bPendingEquip = false;
    	CurrentState = EWeaponState::Idle;
    }

I deleted most of the rest of my class, so you only see the constructor.

I notice right off the bat that the signature for your constructor is different - you have a parameterless constructor. Is there some documentation on the lifecycle of a C++ object in Unreal? I haven’t seen that anywhere yet…

Changing my constructor to be parameterless one ends up giving me the error error C2512: 'AHUD' : no appropriate default constructor available, probaby due to the fact that the AHUD superclass does not have a default constructor (AActor [used in your code] does have a default constructor).

As far as i understood, you can create your own constructors with 4.6 and don’t need to use the one with the objectinitializer.

I am going to bed now. If you leave me a comment i will have a look at this tomorrow.

Also try to recreate this in an Actor class. Maybe you are right. Haven’t worked with the canvas for long.

In the absence of any other answer, I would appreciate it, of course.

Please try to change your constructor declaration from “ATestHud::ATestHud” to “ATestHud”.

The UHT is trying to detect if you have declared your own constructor and then generate code accordingly. I’m quite sure we’re not supporting the declaration with the namespace operator.

TBH this type of declaration is legal, but it’s rather uncommon.

Jarek

Ah ok. That is one of those things where using “normal” c++ doesn’t work. Since i AM declaring my own Constructor, i need to stick to the normal namespace version. The default constructor made by epic only uses the constructor name, or?

Currently many engine classes still do not have default constructors, so any time you derive from such a class, you will need to provide the FObjectInitializer version and pass it on to the base. I believe the move to default constructors is being made, but it may take some time before all classes have them.

As to your other error, see Jarek’s answer. I don’t recall ever seeing that syntax with a fully qualified name used within the class declaration, to be honest I’m surprised to learn that it’s legal C++.

Also, your constructor appears to be private in the code you posted, which I suspect would lead to further errors if not changed.

Yes, I did remove the fully qualified name from my header (it was a copy/paste error I didn’t catch until after I pasted that code into my question), but that really isn’t the problem. Ditto with the private/public visibility (well, this might have been a problem, but different than what I’m asking about here). I’ll update my question tonight when I get home.

Is there documentation on the build process? I didn’t know Unreal scanned my code and altered its generated code based upon this… Anyway, as mentioned in a comment on another answer, I’ll ensure I’ve tried this tonight and post the results.

In that case the error you’re getting sounds like what I’d expect if you had used the old GENERATED_UCLASS_BODY macro, rather than the new GENERATED_BODY one. The former declared the constructor for you, the latter should leave it up to you. If you’re getting this error with the new version, I don’t know what the cause would be.

Yes, we’re generating code for you. We do this using a couple of macros e.g. GENERATED_BODY().

The second error you get is due to AHUD not having a default constructor yet. We’re in the process of changing all Engine classes, but we’re not there yet in 4.7.

So, to construct an object you have to execute it’s base class’ constructor. AHUD have only one constructor AHUD(const FObjectInitializer& ObjectInitializer). Hence, for now, you have to have a constructor with FObjectInitializer to pass it down to base class.

Please, retry your original code with alterations I mentioned earlier and let me know if that helped.

Yep, that fixed it. I thought I had tried this, but apparently not.

I’m amazed though that this question is already marked resolved… I figured I would have to do that.

I’m pretty new to Unreal. But I seemed to fix this problem by referencing the parent class constructor like so…

AHUDMenu::AHUDMenu(const class FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)

I don’t know if this is the correct way of getting around this… but it works :slight_smile: