Looking to get some advice on passing arguments to constructors

Hey all,

I’ve posted this over in the forums but I haven’t received any replies so I thought it’d be a good idea to post here and see if anyone can help this snag I’ve hit.

The book I’m running through now is walking me through creating a CombatAction which is inheriting from a class called ICombatAction.
Inside the ICombactAction.h, it’s just declaring two virtual functions to be overriden, BeginExecuteAction(which takes an argument of a custom Character class) and Execute Action(which takes in an argument of DeltaSeconds).

So creating the TestCombatAction.h, it describes to declare

public:
TestCombatAction(UGameCharacter* target);

and in the cpp. file to type the constructor as

TestCombatAction::TestCombatAction(UGameCharacter* target)
{
  this->target = target;
}

However, I thought this was weird as I’ve been using constructors up to this point as

(const FObjectInitializer& ObjectInitializer)
      : Super(ObjectInitializer)

And sure enough this flipped out

TestCombatAction.cpp(7) : error C2084: function 'TestCombatAction::TestCombatAction(UGameCharacter *)' already has a body

The use of the TestCombatAction is to be used as an action which takes in a target and would be using UFUNCTIONs inside the header to expose to the UI Widget Blueprint as well as describing me to use it in classes as

this->action = new TestCombatAction(target);

So with all that in mind, is there a way to pass an argument into the constructor alongside the FObjectInitializer or is there an alternate way of doing this?

Not possible in UE4. To pass arguments you must create some kind of Init () method and call it after calling SpawnActor or NewObject.

So would that mean I would create the initial constructor as
TestCombatAction::TestCombatAction(FObjectInitializer &ObjectInitializer) : Super(ObjectInitializer)
{
}

with the function

TestCombatAction::Init(UGameCharacter* target)
{
 this->target = target;
}

below.

And instead of

this->action = new TestCombatAction(target);

I would call it as

this->action = NewObject(target);
TestObjectAction::Init(target);

?

Absolutely correct (assuming this->action is a UObject). Though it would be closer to the following:

this->action = NewObject<WhateverClassActionIs>(WhateverClassActionIs::StaticClass());
this->action->Init(target);

Excellent! I’ll give that a shot.
I’m pretty sure it’s a UObject (I’ve started c++ from c# a few days ago, so there’s a few gaps in my head about definitions).
The only thing I can think of that might affect it is that it inherits from a base interface class called ICombatAction

ICombatAction.h

#include "GameCharacter.h"

class UGameCharacter;

class ICombatAction
{
public:
	virtual void BeginExecuteAction(UGameCharacter* character) = 0;
	virtual bool ExecuteAction(float DeltaSeconds) = 0;
};

I’ll give it a shot nonetheless and see what happens!

Edit : I just re-read what you said and yeah that should be right
I’ll come back and mark this as an answer if all goes swimmingly

I forgot code blocks and they like to strip chevrons here, so it butchered the code.

It doesn’t matter if your class inherits an interface. As long as it inherits from UObject at some point you can use NewObject. It is the same as C# classes - a class is considered both its class, all of its parents, and any interfaces attached to it.

Right, gotcha!

Ok everything seems to be working except for the Init function.
I’ve declared the Init function as

void Init(UGameCharacter* target);

directly below the constructor in the header file but it kicks back giving me a ‘missing type specifier’ error.
Do I need to set its return value to the actual TestCombatAction object itself?

Might give that a try

Edit : Scratch all that. I’m an idiot. I forgot to put the void return type in the cpp file buries head in hands haha

It’s giving me a linker error now towards the Combat UI Widget where AttackTarget (an exposed blueprint function in Combat UI Widget script that exposes the target for use with the TestCombatAction), but that’s probably down to some weird circular dependency I’ve done.

Thanks for you help, I really appreciate you being so ■■■■ patient! haha

Add the keyword “class” just before UGameCharacter*. Since the header doesn’t know what UGameCharacter is (without including the UGameCharacter header file which you don’t want to do unless you absolutely have to) you need to tell it that it is a class pointer. This way the compiler can allocate enough memory for “some kind of class pointer”, and by including the UGameCharacter header in the cpp file the compiler can finally resolve what kind of pointer it is.