Do I have to use FObjectInitializer in constructor?

I see some classes don’t have FObjectInitializer in their constructor, while others do. I wonder what the difference is here?

Thanks,

wcl1993

They are both valid unreal engine class constructor, FObjectInitializer has some very useful function to initialize the object properties but some simple classes don’t really need that functionalities, and that is why, I think, Epic made an alternative constructor that has no parameter, just to make things simple and tidy.

I don’t know when Epic added the capability of creating this simple constructor, but I remembered that before 4.5 you can’t create such a thing and it’s kinda waste having to write object initializer (it was called PCIP back then), call the super constructor and then never use it in the constructor because what I wanted to do is to just set the default value of some simple properties.

Exactly! Sometimes I only need to set some default values and using it would be very redundant.

They are the same. The difference is that the 1 constructor takes an initializer, the other constructor, creates the initializer, and routes all the CreateCalls through the Initializer behind the scenes. The change is because people are too lazy to type out the Initializer…

Nope, take a look at the two constructors in Actor.cpp, note the comment in the second constructor.

AActor::AActor()
{
	InitializeDefaults();
}

AActor::AActor(const FObjectInitializer& ObjectInitializer)
{
	// Forward to default constructor (we don't use ObjectInitializer for anything, this is for compatibility with inherited classes that call Super( ObjectInitializer )
	InitializeDefaults();
}
3 Likes

You are correct in how AActor implements it,

  • AActor doesn’t care about ObjectInitializer itself.
  • Epic made AActor(const FObjectInitializer&) exist so that subclasses could safely rely on ObjectInitializer when needed.
  • Unreal Engine’s object construction system always tries to call the constructor with FObjectInitializer if available.
  • subobjects like AbilitySystemComponent and AttributeSets can use that system

See below for reference code example in Lyra’s GAS character

ALyraCharacterWithAbilities::ALyraCharacterWithAbilities(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	AbilitySystemComponent = ObjectInitializer.CreateDefaultSubobject<ULyraAbilitySystemComponent>(this, TEXT("AbilitySystemComponent"));
	AbilitySystemComponent->SetIsReplicated(true);
	AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);

	// These attribute sets will be detected by AbilitySystemComponent::InitializeComponent. Keeping a reference so that the sets don't get garbage collected before that.
	HealthSet = CreateDefaultSubobject<ULyraHealthSet>(TEXT("HealthSet"));
	CombatSet = CreateDefaultSubobject<ULyraCombatSet>(TEXT("CombatSet"));

	// AbilitySystemComponent needs to be updated at a high frequency.
	NetUpdateFrequency = 100.0f;
}

TLDR - FObjectInitializer is not required to provide in the constructor unless the parent class’s constructor needs it, or if you want to access some functionality like replacing a parent class’s component class.