宏 GENERATED_UCLASS_BODY() 与 GENERATED_BODY() 简析

发布时间 2023-05-26 15:55:31作者: tomato-haha


继承自UE4引擎的类会生成一些宏代码。 这此宏代码的作用就是帮助生成构造函数和相关成员函数


  1. UCLASS()
  2. class SECTION1_API ASUsableActor : public AActor
  3. {
  4. GENERATED_BODY()
  5. public:
  6. };



  1. UCLASS()
  2. class SURVIVALGAME_API ASUsableActor : public AActor
  3. {
  4. GENERATED_UCLASS_BODY()
  5. public:
  6. };


F12跳转到这两个宏的声明文件中

  1. #define GENERATED_BODY() \
  2. PRAGMA_DISABLE_DEPRECATION_WARNINGS \
  3. public: \
  4. ASUsableActor_RPC_WRAPPERS_NO_PURE_DECLS \
  5. ASUsableActor_CALLBACK_WRAPPERS \
  6. ASUsableActor_INCLASS_NO_PURE_DECLS \
  7. ASUsableActor_ENHANCED_CONSTRUCTORS \
  8. private: \
  9. PRAGMA_POP


GENERATED_BODY() 会经过一系列的宏替换  最下边成员访问方式为 private:  也就是说紧随 GENERATED_BODY()之后而又没有显著更改成员访问方式,那么访问方式则为private 


  1. #define GENERATED_UCLASS_BODY() \
  2. PRAGMA_DISABLE_DEPRECATION_WARNINGS \
  3. public: \
  4. ASUsableActor_RPC_WRAPPERS \
  5. ASUsableActor_CALLBACK_WRAPPERS \
  6. ASUsableActor_INCLASS \
  7. ASUsableActor_STANDARD_CONSTRUCTORS \
  8. public: \
  9. PRAGMA_POP

而GENERATED_UCLASS_BODY()  后边声名的成员变量访问方式则为公有。


  1. #define ASUsableActor_RPC_WRAPPERS
  2. #define ASUsableActor_CALLBACK_WRAPPERS

这两个为空宏, 在C/C++ 中空宏会被空格替换    大多用来表示注释


GENERATED_UCLASS_BODY() 中的两个非空宏声明如下

  1. #define ASUsableActor_INCLASS \
  2. private: \
  3. static void StaticRegisterNativesASUsableActor(); \
  4. friend SECTION1_API class UClass* Z_Construct_UClass_ASUsableActor(); \
  5. public: \
  6. DECLARE_CLASS(ASUsableActor, AActor, COMPILED_IN_FLAGS(0), 0, Section1, NO_API) \
  7. DECLARE_SERIALIZER(ASUsableActor) \
  8. /** Indicates whether the class is compiled into the engine */ enum {IsIntrinsic=COMPILED_IN_INTRINSIC}; \
  9. UObject* _getUObject() const { return const_cast<ASUsableActor*>(this); }

这几行主要是为类声明一些成员方法

  1. #define ASUsableActor_STANDARD_CONSTRUCTORS \
  2. /** Standard constructor, called after all reflected properties have been initialized */ \
  3. NO_API ASUsableActor(const FObjectInitializer& ObjectInitializer); \
  4. DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL(ASUsableActor) \
  5. private: \
  6. /** Private copy-constructor, should never be used */ \
  7. NO_API ASUsableActor(const ASUsableActor& InCopy); \
  8. public:

这里可以看到 声明了一个公有构造函数  和一个私有的拷贝构造函数, 公有构造函数参数为FObjectInitializer的引用常量。 而拷贝构造函数声明为私有,则表示拷贝构造函数不可用



下边两个是 GENERATED_BODY()  中引用的非空宏声明

  1. #define ASUsableActor_RPC_WRAPPERS_NO_PURE_DECLS \
  2. static inline void StaticChecks_Implementation_Validate() \
  3. { \
  4. }

  1. #define ASUsableActor_INCLASS_NO_PURE_DECLS \
  2. private: \
  3. static void StaticRegisterNativesASUsableActor(); \
  4. friend SECTION1_API class UClass* Z_Construct_UClass_ASUsableActor(); \
  5. public: \
  6. DECLARE_CLASS(ASUsableActor, AActor, COMPILED_IN_FLAGS(0), 0, Section1, NO_API) \
  7. DECLARE_SERIALIZER(ASUsableActor) \
  8. /** Indicates whether the class is compiled into the engine */ enum {IsIntrinsic=COMPILED_IN_INTRINSIC}; \
  9. UObject* _getUObject() const { return const_cast<ASUsableActor*>(this); }


  1. #define ASUsableActor_ENHANCED_CONSTRUCTORS \
  2. private: \
  3. /** Private copy-constructor, should never be used */ \
  4. NO_API ASUsableActor(const ASUsableActor& InCopy); \
  5. public: \
  6. DEFINE_DEFAULT_CONSTRUCTOR_CALL(ASUsableActor)

DEFINE_DEFAULT_CONSTRUCTOR_CALL 在VS中并没有跟踪到在何处如何声明, 根据字面解释应该是定义默认的构造函数,也就是最基本的构造函数。

同样拷贝构造函数不可用


通过以上分析可以认为 GENERATED_BODY()为我们生成默认构造函数,  而GENERATED_UCLASS_BODY() 为我们生成带有指定参数类型的构造函数