创建一个MyClassTest.h文件和MyClassTest.cpp文件:
MyClassTest.h
MyClassTest.cpp文件
编译后会生成文件名.generated.h和文件名.gen.cpp文件。

接下来看MyClassTest.h中的GENERATED_BODY():
在ObjectMacros.h文件中对此宏做了一层层定义,

  • 可以看出GENERATED_BODY()最终会转换为一个由文件ID(CURRENT_FILE_ID)、行号(LINE)、"GENERATED_BODY"字符组合成的标记。

在这里插入图片描述
在这里插入图片描述
(可以看出来这个CURRENT_FILE_ID是该.h文件所在项目的路径)
(其中行号是GENERATED_BODY在.h文件中的行号)
综上可得 GENERATED_BODY() 转换为了Survive_Source_MYUEPROJECT_Public_MyClassTest_h_15_GENERATED_BODY
在这里插入图片描述

  • 而这个结果在.generated.h文件中又继续宏定义了:

在这里插入图片描述

  • 需要继续一步步展开:

在这里插入图片描述
PRAGMA_DISABLE_DEPRECATION_WARNINGS/PRAGMA_ENABLE_DEPRECATION_WARNINGS
(这两个宏是用来开启/关闭禁止编译器过期警告.)
综上最终GENERATED_BODY()展开差不多就变为了:
在这里插入图片描述
MyClassTest.gen.cpp文件内容如下:

#include "GeneratedCppIncludes.h"
#include "Public/MyClassTest.h"
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable : 4883)
#endif
PRAGMA_DISABLE_DEPRECATION_WARNINGS
void EmptyLinkFunctionForGeneratedCodeMyClassTest() {}//链接占位符,帮助保证UBT生成的代码在编译后的二进制文件中是可链接的
// Cross Module References
	MYUEPROJECT_API UClass* Z_Construct_UClass_UMyClassTest_NoRegister();//返回一个指向 UMyClassTest 类的 UClass 指针,但不进行注册,这样可以访问这个类的特性,但不会将其注册到引擎的内存管理系统中 确保了类的快速查询而不进行实际注册,帮助优化性能和维护引擎的稳定性
	MYUEPROJECT_API UClass* Z_Construct_UClass_UMyClassTest();//完整的类构造和注册过程的实现
	COREUOBJECT_API UClass* Z_Construct_UClass_UObject();//构造和注册 UObject 类及其属性和方法
	UPackage* Z_Construct_UPackage__Script_myueproject();//Win64\UE4Editor\Inc\myueproject下有myueproject.init.gen.cpp文件实现了函数
// End Cross Module References
	void UMyClassTest::StaticRegisterNativesUMyClassTest()//将定义的本地方法注册到引擎的反射系统中
	{
		UClass* Class = UMyClassTest::StaticClass();
		static const FNameNativePtrPair Funcs[] = {
			{ "MyFunc", (Native)&UMyClassTest::execMyFunc },
		};
		FNativeFunctionRegistrar::RegisterFunctions(Class, Funcs, ARRAY_COUNT(Funcs));
	}
	UFunction* Z_Construct_UFunction_UMyClassTest_MyFunc()
	{
		struct MyClassTest_eventMyFunc_Parms
		{
			uint32 a;
			int32 ReturnValue;
		};
		static UFunction* ReturnFunction = nullptr;
		if (!ReturnFunction)
		{
			static const UE4CodeGen_Private::FIntPropertyParams NewProp_ReturnValue = { UE4CodeGen_Private::EPropertyClass::Int, "ReturnValue", RF_Public|RF_Transient|RF_MarkAsNative, 0x0010000000000580, 1, nullptr, STRUCT_OFFSET(MyClassTest_eventMyFunc_Parms, ReturnValue), METADATA_PARAMS(nullptr, 0) };
			static const UE4CodeGen_Private::FUInt32PropertyParams NewProp_a = { UE4CodeGen_Private::EPropertyClass::UInt32, "a", RF_Public|RF_Transient|RF_MarkAsNative, 0x0010000000000080, 1, nullptr, STRUCT_OFFSET(MyClassTest_eventMyFunc_Parms, a), METADATA_PARAMS(nullptr, 0) };
			static const UE4CodeGen_Private::FPropertyParamsBase* const PropPointers[] = {
				(const UE4CodeGen_Private::FPropertyParamsBase*)&NewProp_ReturnValue,
				(const UE4CodeGen_Private::FPropertyParamsBase*)&NewProp_a,
			};
#if WITH_METADATA
			static const UE4CodeGen_Private::FMetaDataPairParam Function_MetaDataParams[] = {
				{ "ModuleRelativePath", "Public/MyClassTest.h" },
			};
#endif
			static const UE4CodeGen_Private::FFunctionParams FuncParams = { (UObject*(*)())Z_Construct_UClass_UMyClassTest, "MyFunc", RF_Public|RF_Transient|RF_MarkAsNative, nullptr, (EFunctionFlags)0x04020401, sizeof(MyClassTest_eventMyFunc_Parms), PropPointers, ARRAY_COUNT(PropPointers), /*0, 0,*/ METADATA_PARAMS(Function_MetaDataParams, ARRAY_COUNT(Function_MetaDataParams)) };
			UE4CodeGen_Private::ConstructUFunction(ReturnFunction, FuncParams);
		}
		return ReturnFunction;
	}
	UClass* Z_Construct_UClass_UMyClassTest_NoRegister()
	{
		return UMyClassTest::StaticClass();
	}
	UClass* Z_Construct_UClass_UMyClassTest()
	{
		static UClass* OuterClass = nullptr;
		if (!OuterClass) // 只构造一次UClass
		{
			static UObject* (*const DependentSingletons[])() = {//列出了UMyClassTest类所依赖的父类和模块
				(UObject* (*)())Z_Construct_UClass_UObject,
				(UObject* (*)())Z_Construct_UPackage__Script_myueproject,
			};
			static const FClassFunctionLinkInfo FuncInfo[] = {

				{ &Z_Construct_UFunction_UMyClassTest_MyFunc, "MyFunc" }, // 类中的方法的信息

			};
#if WITH_METADATA
			static const UE4CodeGen_Private::FMetaDataPairParam Class_MetaDataParams[] = {//存储类的元数据,例如类的头文件路径和相对模块路径
				{ "IncludePath", "MyClassTest.h" },
				{ "ModuleRelativePath", "Public/MyClassTest.h" },
			};
#endif
#if WITH_METADATA
			static const UE4CodeGen_Private::FMetaDataPairParam NewProp_MyID_MetaData[] = {//变量属性数据
				{ "ModuleRelativePath", "Public/MyClassTest.h" },
			};
#endif
			//NewProp_MyID属性的类型、访问修饰符、元数据等
			static const UE4CodeGen_Private::FIntPropertyParams NewProp_MyID = { UE4CodeGen_Private::EPropertyClass::Int, "MyID", RF_Public|RF_Transient|RF_MarkAsNative, 0x0010000000000000, 1, nullptr, STRUCT_OFFSET(UMyClassTest, MyID), METADATA_PARAMS(NewProp_MyID_MetaData, ARRAY_COUNT(NewProp_MyID_MetaData)) };
			static const UE4CodeGen_Private::FPropertyParamsBase* const PropPointers[] = {//包含类中所有属性的指针。这些指针用于反射和序列化时的属性访问。
				(const UE4CodeGen_Private::FPropertyParamsBase*)&NewProp_MyID,
			};
			static const FCppClassTypeInfoStatic StaticCppClassTypeInfo = {
				TCppClassTypeTraits<UMyClassTest>::IsAbstract,//该类是否是一个抽象类
			};
			static const UE4CodeGen_Private::FClassParams ClassParams = {//包含了所有与UMyClassTest类有关的参数
				&UMyClassTest::StaticClass,
				DependentSingletons, ARRAY_COUNT(DependentSingletons),
				0x00000080u,
				FuncInfo, ARRAY_COUNT(FuncInfo),
				PropPointers, ARRAY_COUNT(PropPointers),
				nullptr,
				&StaticCppClassTypeInfo,
				nullptr, 0,
				METADATA_PARAMS(Class_MetaDataParams, ARRAY_COUNT(Class_MetaDataParams))
			};
			UE4CodeGen_Private::ConstructUClass(OuterClass, ClassParams);//调用引擎构造接口来实际构造UClass对象并进行注册
		}
		return OuterClass;
	}
	IMPLEMENT_CLASS(UMyClassTest, 10187216);//编译时调用构造函数来注册特定的类,据说会调用Z_Construct_UClass_UMyClassTest构造函数 
	//<==>IMPLEMENT_CLASS宏展开如下:
	//static UMyClassTestCompiledInDefer<UMyClassTest> AutoInitialize##UMyClassTest(TEXT(#UMyClassTest), sizeof(UMyClassTest), 10187216);
	//UClass* UMyClassTest::GetPrivateStaticClass() 
	//{ 
	//	static UClass* PrivateStaticClass = NULL; 
	//	if (!PrivateStaticClass) 
	//	{ 
	//		/* this could be handled with templates, but we want it external to avoid code bloat */ 
	//		GetPrivateStaticClassBody(
	//			StaticPackage(), 
	//			(TCHAR*)TEXT(#UMyClassTest) + 1 + ((StaticClassFlags & CLASS_Deprecated) ? 11 : 0), 
	//			PrivateStaticClass, 
	//			StaticRegisterNatives##UMyClassTest, 
	//			sizeof(UMyClassTest), 
	//			(EClassFlags)UMyClassTest::StaticClassFlags, 
	//			UMyClassTest::StaticClassCastFlags(), 
	//			UMyClassTest::StaticConfigName(), 
	//			(UClass::ClassConstructorType)InternalConstructor<UMyClassTest>, 
	//			(UClass::ClassVTableHelperCtorCallerType)InternalVTableHelperCtorCaller<UMyClassTest>, 
	//			& UMyClassTest::AddReferencedObjects, 
	//			& UMyClassTest::Super::StaticClass, 
	//			& UMyClassTest::WithinClass::StaticClass 
	//		); 
	//	} 
	//		return PrivateStaticClass; 
	//}



	static FCompiledInDefer Z_CompiledInDefer_UClass_UMyClassTest(Z_Construct_UClass_UMyClassTest, &UMyClassTest::StaticClass, TEXT("/Script/myueproject"), TEXT("UMyClassTest"), false, nullptr, nullptr, nullptr);
	DEFINE_VTABLE_PTR_HELPER_CTOR(UMyClassTest);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
#ifdef _MSC_VER
#pragma warning (pop)
#endif

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐