【UEC++学习】UE中智能指针的使用基础

1. 基础理论

C++有了一套智能指针,为何UE要重新设计自己的呢?
(1)std::shared_ptr并不是所有平台通用。
(2)虚幻的智能指针可以与其他容器更好的协作,如TArray
(3)确保线程的安全与优化。

智能指针的原理: 使用引用计数,当引用计数为0时,会自动析构。

UE的智能指针的类型:
(1)TSharedPtr<class ObjectType, ESPMode Mode>:共享指针
(2)TSharedRef<class ObjectType, ESPMode Mode>:共享引用
(3)TWeakPtr<class ObjectType, ESPMode Mode>:弱指针
(4)TSharedFromThis<class OtherType, ESPMode OtherMode>:this智能指针

TSharedPtr与TSharedRef的区别: TSharedRef不能为空,这是唯一的区别

弱指针的作用:
(1)解决循环引用问题。
(2)不对资源的生命周期进行控制,只能使用资源,并不对资源进行竞争。比如:可以有线程专门管理资源的生命周期,而有些线程不关心资源的生命周期,只关心资源的使用问题,这时就可以使用弱指针只去使用这个资源。
(3)因为弱指针不管理生命周期,所以对其进行是否有效的判断是很有必要的。

2. TSharedPtr

/**
 * TSharedPtr是一个宏,需要传入两个参数
 * ObjectType:
 * InMode:指明线程是否安全
 */
template< class ObjectType, ESPMode InMode >
class TSharedPtr
{
	//.................
}

/** ESPMode的枚举 */
enum class ESPMode : uint8
{
	// 线程不安全
	NotThreadSafe = 0,
	// 线程安全
	ThreadSafe = 1,
	// 灵活的Fast
	Fast UE_DEPRECATED(5.0, "ESPMode::Fast has been deprecated - please use ESPMode::ThreadSafe instead") = 1
};

/** 提供的特化版本,默认使用ThreadSafe版本 */
template< class ObjectType, ESPMode Mode = ESPMode::ThreadSafe > class TSharedRef;
template< class ObjectType, ESPMode Mode = ESPMode::ThreadSafe > class TSharedPtr;
template< class ObjectType, ESPMode Mode = ESPMode::ThreadSafe > class TWeakPtr;
template< class ObjectType, ESPMode Mode = ESPMode::ThreadSafe > class TSharedFromThis;

创建:MakeShareable()

template< class ObjectType >
[[nodiscard]] FORCEINLINE SharedPointerInternals::TRawPtrProxy< ObjectType > MakeShareable( ObjectType* InObject )
{
	return SharedPointerInternals::TRawPtrProxy< ObjectType >( InObject );
}

重载->运算符,本质返回ObjectType*,相当于返回我们共享指针指向对象的指针,我们就可以调用其所有的方法和变量了。

常用的函数如下:

/** 创建TSharedPtr */
TSharedPtr<FTestCppClass> TestSharedPtr = MakeShareable(new FTestCppClass());
/** 判断是否有效 */
if(TestSharedPtr.IsValid())
{
	TestSharedPtr->TestFun();
}
/** 获取引用计数 */
int32 SharedPtrCount = TestSharedPtr.GetSharedReferenceCount();
/** 解引用,返回ObjectType* */
FTestCppClass* Test = TestSharedPtr.Get();
/** 将普通对象的所有权交给智能指针管理 */
FTestCppClass* TestCppClass = new FTestCppClass;
TSharedPtr<FTestCppClass> TestSharedPtr(MakeShareable(TestCppClass ));
/** Reset() 相当于 TestSharedPtr = nullptr */
TestSharedPtr.Reset();
/** Reset()源码 */
FORCEINLINE void Reset()
{
	*this = TSharedPtr< ObjectType, Mode >();
}

3. TSharedRef

/** 创建共享引用 */
// 构造创建
TSharedRef<FTestCppClass> TestSharedRef(new FTestCppClass());
// 通过隐式转化创建
TSharedRef<FTestCppClass> TestSharedRef1 = MakeShareable(new FTestCppClass());

/** 获取引用计数 */
int32 SharedRefCount = TestSharedRef.GetSharedReferenceCount();

注意:TSharedRef不能置空,也就是必须有初始值,并且TSharedRef没有Reset()

4. TSharedPtr与TSharedRef的转化

/** 共享指针转化为共享引用 */
{
	TSharedPtr<FTestCppClass> TestPtr = MakeShareable(new FTestCppClass);
	TSharedRef<FTestCppClass> TestRef = TestPtr.ToSharedRef();
}
/** 共享引用转化为共享指针 */
{
	TSharedRef<FTestCppClass> TestRef = MakeShareable(new FTestCppClass);
	TSharedPtr<FTestCppClass> TestPtr = TestRef;
}

StaticCastSharedPtr/StaticCastSharedRef:父子级之间的转化
ConstCastSharedPtr/ConstCastSharedRef:将“常量”转化为“可变”的

/** 父子级之间的转化 */
{
	TSharedPtr<FTestBaseClass> FatherPtr = MakeShareable(new FTestCppClass);
	if(FatherPtr.IsValid())
	{
		// 将父类转化为子类
		TSharedPtr<FTestCppClass> ChildrenPtr = StaticCastSharedPtr<FTestCppClass>(FatherPtr);
	}
}
/** 将“常量”转化为“可变”的 */
{
	const TSharedPtr<FTestBaseClass> FatherPtr = MakeShareable(new FTestBaseClass);
	if(FatherPtr.IsValid())
	{
		// 将父类转化为子类
		TSharedPtr<FTestBaseClass> ChildrenPtr = ConstCastSharedPtr<FTestBaseClass>(FatherPtr);
	}
}

5. TWeakPtr

弱指针的作用和C++一致,通过引用计数不加1,用来解决智能指针的循环引用问题,这里不进行赘述…

6. TSharedFromThis

作用:继承自TSharedFromThis<class OtherType, ESPMode OtherMode>的类,自带一个弱指针,可以将this作为智能指针进行传递或管理。

/** 传递this指针 */
class FTestCppClass;

class FTestBaseClass
{
public:
	void TestFun(const TSharedPtr<FTestCppClass>& TestCppClass)
	{
		
	}
};

class FTestCppClass : public TSharedFromThis<FTestCppClass>
{
public:
	void NotifyUpdate()
	{
		FTestBaseClass TestBaseClass;
		// 将this指针当作智能指针进行传递
		TestBaseClass.TestFun(this->AsShared());
	}
};

/** 将继承自TSharedFromThis的类转化为智能指针 */
FTestCppClass* TestCppClass = new FTestCppClass;
TSharedPtr<FTestCppClass> TestSharedPtr = TestCppClass->AsShared();
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值