- Unreal Engine 4 Scripting with C++ Cookbook
- William Sherif Stephen Whittle
- 505字
- 2021-07-08 10:50:50
Managed memory – using NewObject< > and ConstructObject< >
Managed memory refers to memory that is allocated and deallocated by some programmed subsystem above the new
, delete
, malloc,
and free
calls in C++. These subsystems are commonly created so that the programmer does not forget to release memory after allocating it. Unreleased, occupied, but unused memory chunks are called memory leaks. For example:
for( int i = 0; i < 100; i++ ) int** leak = new int[500]; // generates memory leaks galore!
In the preceding example, the memory allocated is not referenceable by any variable! So you can neither use the allocated memory after the for
loop, nor can you free it. If your program allocates all available system memory, then what will happen is that your system will run out of memory entirely, and your OS will flag your program and close it for using up too much memory.
Memory management prevents forgetting to release memory. In memory-managed programs, it is commonly remembered by objects that are dynamically allocated the number of pointers referencing the object. When there are zero pointers referencing the object, it is either automatically deleted immediately, or flagged for deletion on the next run of the garbage collector.
Use of managed memory is automatic within UE4. Any allocation of an object to be used within the engine must be done using NewObject< >()
or SpawnActor< >()
. The release of objects is done by removing the reference to the object, then occasionally calling the garbage cleanup routine (listed further in this chapter).
Getting ready
When you need to construct any UObject
derivative that is not a derivative of the Actor
class, you should always use NewObject< >
. SpawnActor< >
should be used only when the object is an Actor
or its derivative.
How to do it...
Say we are trying to construct an object of type UAction
, which itself derives from UObject
. For example, the following class:
UCLASS(BlueprintType, Blueprintable, meta=(ShortTooltip="Base class for any Action type") ) Class WRYV_API UAction : public UObject { GENERATED_UCLASS_BODY() public: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Properties) FString Text; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Properties) FKey ShortcutKey; };
To construct an instance of the UAction
class, we'd do the following:
UAction* action = NewObject<UAction>( GetTransientPackage(), UAction::StaticClass() /* RF_* flags */ );
How it works…
Here, UAction::StaticClass()
gets you a base UClass*
for the UAction
object. The first argument to NewObject< >
is GetTransientPackage()
, which simply retrieves the transient package for the game. A package (UPackage
) in UE4 is just a data conglomerate. Here we use the Transient Package to store our heap-allocated data. You could also use UPROPERTY() TSubclassOf<AActor>
from Blueprints to select a UClass
instance.
The third argument (optional) is a combination of parameters that indicate how UObject
is treated by the memory management system.
There's more…
There is another function very similar to NewObject< >
called ConstructObject< >
. ConstructObject< >
provides more parameters in construction, and you may find it useful if you need to specify these parameters. Otherwise, NewObject
works just fine.
See also
- You may also want to see the documentation for
RF_*
flags at https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/Objects/Creation/index.html#objectflags
- Bootstrap Site Blueprints Volume II
- JavaScript全程指南
- 新一代通用視頻編碼H.266/VVC:原理、標準與實現
- 微信公眾平臺開發:從零基礎到ThinkPHP5高性能框架實踐
- JSP開發案例教程
- Raspberry Pi Home Automation with Arduino(Second Edition)
- Terraform:多云、混合云環境下實現基礎設施即代碼(第2版)
- PHP從入門到精通(第4版)(軟件開發視頻大講堂)
- Building Serverless Architectures
- Ext JS 4 Plugin and Extension Development
- H5+移動營銷設計寶典
- Spark技術內幕:深入解析Spark內核架構設計與實現原理
- Android應用程序設計
- HTML5+CSS3+JavaScript案例實戰
- JSP編程教程