#memo

indiedev太郎

UObjectのコンストラクタのバリエーション

UObjectのコンストラクタの話、宣言に3つのバリエーションが有る

  1. ClassName() のデフォルトコンストラクタ
  2. ClassName(const class FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) の形をとるもの
  3. 何も宣言しない(GENERATED_BODY()のみ)

こちらのページでも2種類あることが解説されているが、何が違うのかがよくわからない

Unreal Engine | ゲームプレイ クラス

2種類宣言されていたらどちらが呼ばれるのか

とりあえず同時に二種類のコンストラクタを実装した場合、どちらが呼ばれるのかを確認してみる

UCLASS()
class AHogeA : public AActor
{
	GENERATED_BODY()

public:
	AHogeA()
	{
		UE_LOG(LogTemp, Warning, TEXT("Called HogeA Default Constructor"));
	}

	AHogeA(const class FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
	{
		UE_LOG(LogTemp, Warning, TEXT("Called HogeA ObjectInitializer Constructor"));
	}
};

https://i.gyazo.com/9b165f333e3492acdab995e4eb65ae4f.png

二つ実装されていたら、ObjectInitializerのほうが呼ばれている、そこでこのクラスを継承した、デフォルトコンストラクタしか用意されていないHogeBクラスを作成し確認してみる

https://i.gyazo.com/a9685d86157438ee7e386ef4171083b7.png

こちらではデフォルトコンストラクタが呼ばれている、更に親のコンストラクタもデフォルトコンストラクタとなっている

更にHogeBクラスを継承したHogeCではObjectInitializerの形のみのコンストラクタを実装すると、これはコンパイルがとおらない、HogeBではObjectInitializerコンストラクタは自動生成されていない

そこでHogeCは以下のようにGENERATED_BODY()マクロのみの実装としてみる

UCLASS()
class AHogeB : public AHogeA
{
	GENERATED_BODY()

public:
	AHogeB()
	{
		UE_LOG(LogKaeruTD, Warning, TEXT("Called HogeB Default Constructor"));
	}

};

UCLASS()
class AHogeC : public AHogeB
{
	GENERATED_BODY()
};

https://i.gyazo.com/8dc37b6e33541ee4e205eaeb2ac73d01.png


こちらではデフォルトコンストラクタが自動生成される、一方GENERATED_UCLASS_BODY()はObjectInitializer型ですね(こちらは宣言のみ)

AActorのコンストラクタをみる

宣言するタイプによって親の呼び出されるコンストラクタが変わることが確認できたので、次に気になるのはAActorなどの挙動がかわるんではないのかということ

UObject ← AActor ← YourActor

なので、まずはAActorを見に行くと、AActorでは2種類ともコンストラクタが宣言されていて、実装では両方AActor::InitializeDefaults()関数を読んでいるだけ、
しかもObjectInitializer型のコンストラクタはここから上にはSuperで連鎖しておらず、エンジン側では一切これは使ってないとのコメントがある

まとめ
  • 基本的にデフォルトコンストラクタでいい
  • ObjectInitializer使って何かするならそちらを使う

FObjectInitializer | Unreal Engine API Reference