【UE4】共享(智能)指针用法

一、基本概念

在UE4中,继承UObject的类被实例化的对象在内存中可以被UE4的垃圾回收机制管理,从而不用担心内存泄漏等问题。但非继承UObject的普通C++类或结构体则需要被开发者管理,如果管理不善,很容易导致内存泄漏、野指针和程序崩溃等问题。对此,我们可以使用UE4提供的共享指针来创建和管理这些类对象。C++的stl库中也提供了一套智能指针系统来管理内存,但UE4的共享指针比stl库提供的智能指针相比具有以下优势:

  • 跨平台
  • 与UE4引擎容器协调工作
  • 针对平台的优化,如多线程等

UE4提供的共享指针主要有以下类型:TSharedPtr、TSharedRef、TWeakPtr、TUniquePtr。下面将一一介绍它们的用法。

二、UE4智能指针

1. TSharedPtr

使用共享指针创建对象:

TSharedPtr<TestStruct> StructPtr = MakeShareable(new TestStruct());

当使用共享指针时,为保证指针有效,可以使用IsValid判断指针的有效性:

if(StructPtr.IsValid())
{
	StructPtr->Name = "Alter Name";
}

获取普通指针:

StructPtr.Get();

重置指针:

StructPtr.Reset();

判断是否唯一:

StructPtr.IsUnique();

获取引用次数:

StructPtr.GetSharedReferenceCount();

如果共享指针对象离开所在作用域或者当作为类成员变量时,类示例对象析构时,会自动处理共享指针的计数,不需要手动重置。因为在对象析构时,会执行成员变量的析构方法,而共享指针中包含一个用于计数的对象,当共享指针析构时,会调用计数对象的析构方法。

2. TSharedRef

TSharedRef的用法与TSharedPtr大致相似,但与TSharedPtr相比,共享引用更加安全。因为引用不能为空,且无法置空,共享引用的初始化一般通过MakeShared或共享指针的ToSharedRef函数赋值,所以更加安全。一般在函数参数传递和作为返回值时使用,共享引用没有提供IsValid进行有效性判断,如果要判断有效性,可通过Get获取原生指针。

创建共享引用:

TSharedRef<TestStruct> StructRef = MakeShared<TestStruct>(new TestStruct());

共享指针转共享引用:

TSharedPtr<TestStruct> StructPtr = MakeShareable(new TestStruct());
TSharedRef<TestStruct> StructRef = StructPtr.ToSharedRef();

共享引用转共享指针可以直接赋值转换:

TSharedRef<TestStruct> StructRef = MakeShared<TestStruct>(new TestStruct());
TSharedPtr<TestStruct> StructPtr = StructRef;

3. TWeakPtr

TWeakPtr指针与TSharedPtr相比,不参与引用计数。而当TWeakPtr指向的对象不存在共享指针指向时,TWeakPtr将自动失效,所以在使用弱指针时,需要进行有效性判断。
初始化TWeakPtr:

TSharedPtr<TestStruct> StructPtr = MakeShareable(new TestStruct());
TWeakPtr<TestStruct> StructWeakPtr(StructPtr);

使用时,进行有效性判断:

if(StructWeakPtr.IsValid())
{
	StructPtr->Name = "Alter Name";
}

弱指针的Pin函数将会返回一个智能指针,所以弱指针转共享指针为:

TSharedPtr<TestStruct> StructPtr = MakeShareable(new TestStruct());
TWeakPtr<TestStruct> StructWeakPtr(StructPtr);
TSharedPtr<TestStruct> StructPtr2(StructWeakPtr.Pin());

4. TUniquePtr

唯一指针指向的对象只能被唯一指向,所以Unique指针不能赋值给其它指针。
创建TUniquePtr指针:

TUniquePtr<TestStruct> StructPtr = MakeUnique<TestStruct>(new TestStruct());

TUniquePtr指针还提供IsValid有效性判断和Reset重置函数。

5. TSharedFromThis

TSharedFromThis是一个模板类,普通C++函数继承TSharedFromThis类后,类将会保存一个弱指针,当通过智能指针获取到该类的普通指针时,可以通过调用AsShared方法获取到该类的智能指针。简而言之,继承该类的普通C++类可以将智能指针获得的普通指针再转为智能指针。

class FTestClass : TSharedFromThis<FTestClass>
{}

TSharedPtr<FTestClass> TestPtr = MakeShareable(new FTestClass());
FTestClass* TestNormalPtr = TestPtr.Get();
TSharedPtr<FTestClass> TestPtr2 = TestNormalPtr->AsShared();

注意:只有通过智能指针获取的普通指针才能使用AsShared转换为智能指针,否则可能崩溃。因为通过MakeShareable创建智能指针时,才会初始化其弱指针。

  • 5
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值