UObjectのコンストラクタのバリエーション
UObjectのコンストラクタの話、宣言に3つのバリエーションが有る
- ClassName() のデフォルトコンストラクタ
- ClassName(const class FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) の形をとるもの
- 何も宣言しない(GENERATED_BODY()のみ)
こちらのページでも2種類あることが解説されているが、何が違うのかがよくわからない
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")); } };
二つ実装されていたら、ObjectInitializerのほうが呼ばれている、そこでこのクラスを継承した、デフォルトコンストラクタしか用意されていないHogeBクラスを作成し確認してみる
こちらではデフォルトコンストラクタが呼ばれている、更に親のコンストラクタもデフォルトコンストラクタとなっている
更に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() };
こちらではデフォルトコンストラクタが自動生成される、一方GENERATED_UCLASS_BODY()はObjectInitializer型ですね(こちらは宣言のみ)
AActorのコンストラクタをみる
宣言するタイプによって親の呼び出されるコンストラクタが変わることが確認できたので、次に気になるのはAActorなどの挙動がかわるんではないのかということ
UObject ← AActor ← YourActor
なので、まずはAActorを見に行くと、AActorでは2種類ともコンストラクタが宣言されていて、実装では両方AActor::InitializeDefaults()関数を読んでいるだけ、
しかもObjectInitializer型のコンストラクタはここから上にはSuperで連鎖しておらず、エンジン側では一切これは使ってないとのコメントがある
まとめ
- 基本的にデフォルトコンストラクタでいい
- ObjectInitializer使って何かするならそちらを使う