Files
.obsidian
.vs
00-MOC
01-Diary
02-Note
03-UnrealEngine
Animation
Editor
Gameplay
AI
Animation
Code
Debug
GAS
Gameplay
Http
Lyra
Mass
Online
Other
PuerTS
UObject
UnrealSpecifiers
Flags
Meta
Specifier
UCLASS
Blueprint
Category
Config
Development
Instance
DefaultToInstanced
EditInlineNew
NotEditInlineNew.md
Within.md
Scene
Serialization
TypePicker
UHT
UENUM
UFUNCTION
UINTERFACE
UPARAM
UPROPERTY
USTRUCT
UCLASS.md
UENUM.md
UFUNCTION.md
UINTERFACE.md
UPARAM.md
UPROPERTY.md
USTRUCT.md
UnrealSpecifiers.md
Ue4 c++ UProperty反射 PostEditChangeProperty.md
Ue4Object生命周期.jpg
大钊提供的一种获取UE Private函数的方法.md
LevelScene
Math
Mobile
Physical
Plugins
Rendering
Sequence
UI
VirtualProduction
VisualEffect
卡通渲染相关资料
性能优化
流程管理与部署
.keep
03-UnrealEngine.md
04-ComputerGraphics
05-SDHGame
06-DCC
07-Other
08-Assets
09-Templates
.gitattributes
.gitignore
.gitmodules
LICENSE

70 lines
2.1 KiB
Markdown
Raw Normal View History

2024-10-12 17:19:46 +08:00
# Within
- **功能描述:** 指定对象创建的时候必须依赖于OuterClassName的对象作为Outer。
- **引擎模块:** Instance
- **元数据类型:** string="abc"
- **作用机制:** 保存在UClass* UClass::ClassWithin=XXX的XXX中
- **常用程度:★★★**
指定对象创建的时候必须依赖于OuterClassName的对象作为Outer。
此类的对象无法在OuterClassName对象的实例之外存在。这意味着要创建此类的对象需要提供OuterClassName的一个实例作为其Outer对象。
本类在这种情况一般是用来当做子对象来使用的。
## 示例代码:
```cpp
UCLASS(Within= MyClass_Within_Outer)
class INSIDER_API UMyClass_Within :public UObject
{
GENERATED_BODY()
};
UCLASS()
class INSIDER_API UMyClass_Within_Outer :public UObject
{
GENERATED_BODY()
public:
};
```
## 示例结果:
```cpp
//错误Fatal error: Object MyClass_Within None created in Package instead of MyClass_Within_Outer
UMyClass_Within* obj=NewObject<UMyClass_Within>();
//正确:
UMyClass_Within_Outer* objOuter = NewObject<UMyClass_Within_Outer>();
UMyClass_Within* obj=NewObject<UMyClass_Within>(objOuter);
```
## 原理:
生成的UClass的字段UClass* ClassWithin会保存这个信息然后在创建的时候StaticAllocateObject会测试 check(bCreatingCDO || !InOuter || InOuter->IsA(InClass->ClassWithin))。因此需要先创建Within的对象。
```cpp
bool StaticAllocateObjectErrorTests( const UClass* InClass, UObject* InOuter, FName InName, EObjectFlags InFlags)
{
if ( (InFlags & (RF_ClassDefaultObject|RF_ArchetypeObject)) == 0 )
{
if ( InOuter != NULL && !InOuter->IsA(InClass->ClassWithin) )
{
UE_LOG(LogUObjectGlobals, Fatal, TEXT("%s"), *FString::Printf( TEXT("Object %s %s created in %s instead of %s"), *InClass->GetName(), *InName.ToString(), *InOuter->GetClass()->GetName(), *InClass->ClassWithin->GetName()) );
return true;
}
}
}
```
在源码里可以搜索到很多Within的用法
UCLASS(Within=Engine, config=Engine, transient)
class ENGINE_API ULocalPlayer
UCLASS(Abstract, DefaultToInstanced, Within=UserWidget)
class UMG_API UUserWidgetExtension : public UObject
{