UE5的智能指针(UEC++个人学习笔记)

本文介绍了UnrealEngine(UE)自定义的智能指针库,包括TSharedPtr、TWeakPtr和TSharedRef,展示了如何在UE中管理内存,以及它们在避免循环引用和控制对象生命周期方面的功能。
摘要由CSDN通过智能技术生成

核心思想:程序员只管分配堆内存,释放内存交给智能指针。UE有自己的一套内存管理系统,但这只针对与UObject。为了方便对非UObject对象的内存管理,UE设计了一套自己智能指针库。包含:共享指针(TSharedPtr)、弱指针(TWeakPtr)、以及特有的共享硬引用(TSharedRef)。

首先需要创建一个类

class TestA
{
public:
	int a = 0;
	float b = 0;
	TestA()
	{
		a = 0;
		b = 0;

	};
	TestA(int a, float b)
	{
		this->a = a;
		this->b = b;
	};
	~TestA()
	{
		UE_LOG(LogTemp, Warning, TEXT("xiguo"));
	}
private:

};

下面声明三个函数,分别用于测试不同的内容

//测试共享指针
	void TestAFunc();

	//测试共享应用
	void TestBFunc();

	//测试弱指针
	//弱指针能解决循环引用,只对引用对象保留引用权,不参与引用计
	//不能阻止对象被销毁,如果弱指针指向的对象被销毁则弱指针会自动清空
	void TestCFunc();

TestAFunc()

void AMySmartPtrActor::TestAFunc()
{
	//C++中创建指针
	TestA* ptr1 = new TestA(1, 2.0f);

	//共享指针左值初始化
	TSharedPtr<TestA>Sharedptr2(ptr1);//不推荐这种方式,容易混淆共享指针和原生指针
	ptr1 = nullptr;

	//共享指针右值初始化
	TSharedPtr<TestA>Sharedptr3(new TestA(3, 4.0f));

	//拷贝构造函数初始化
	TSharedPtr<TestA>Sharedptr4(Sharedptr2);


	//UE的方法初始化共享指针
	TSharedPtr<TestA>Sharedptr5 = nullptr;//共享指针可以初始化为空
	Sharedptr5 = MakeShareable(new TestA(5, 6.0f));

	//线程安全的共享指针
	TSharedPtr<TestA, ESPMode::ThreadSafe>Sharedptr6(new TestA(7, 8.0f));


	//共享指针常用的接口
	if (Sharedptr5.IsValid())//判断指针是否指向了一个有效的对象
	{
		TSharedRef<TestA>SharedRef1(new TestA(9,10.0f));
		//共享指针转为共享引用,引用计数加一
		SharedRef1 = Sharedptr5.ToSharedRef();

		//获得引用计数
		int32 Count1 = Sharedptr5.GetSharedReferenceCount();
		//这里为2,是MakeShareable还有SharedRef1,一共两个类对象共享同一指针
		UE_LOG(LogTemp, Warning, TEXT("Count is %d"), Count1);
		
		if (!Sharedptr5.IsUnique())
		{
			UE_LOG(LogTemp, Warning, TEXT("sharedptr5 is not Unique"));
		}
		
		//Get的作用是解引用,返回引用对象的原生指针
		Sharedptr5.Get()->a;
		UE_LOG(LogTemp, Warning, TEXT("Shareptr5a is %d"), Sharedptr5.Get()->a);

		//重置共享指针
		Sharedptr5.Reset();
		int32 Count2 = Sharedptr5.GetSharedReferenceCount();
		UE_LOG(LogTemp, Warning, TEXT("Count is %d"), Count2);
	}

}

TestBfunc()

void AMySmartPtrActor::TestBFunc()
{
	//共享引用初始化的时候必须指向一个有效的对象
	TSharedRef<TestA>SharedRef2(new TestA(7, 8.0f)); 
	if (SharedRef2.IsUnique())//
	{
		SharedRef2->a;//虽然是共享引用,但是解引用的方式仍然是->
		UE_LOG(LogTemp, Warning, TEXT("SharedRef2a is %d"), SharedRef2->a);

		TSharedPtr<TestA>Sharedptr6;

		//共享引用转换为共享指针,可以直接转化
		Sharedptr6 = SharedRef2;
		//解引用
		Sharedptr6.Get()->b;
		UE_LOG(LogTemp, Warning, TEXT("Sharedptr6b is %f"), Sharedptr6.Get()->b);
	}

}

 TestCFunc()

void AMySmartPtrActor::TestCFunc()
{
	//测试弱指针
	//弱指针能解决循环引用,只对引用对象保留引用权,不参与引用计
	//不能阻止对象被销毁,如果弱指针指向的对象被销毁则弱指针会自动清空
	TSharedPtr<TestA>Sharedptr7 = MakeShareable(new TestA(10, 11.0f));
	TSharedRef<TestA>SharedRef3(new TestA(12, 13.0f));
	//声明弱指针并初始化
	TWeakPtr<TestA>WeakPtr1(Sharedptr7);
	TWeakPtr<TestA>WeakPtr2(SharedRef3);
	if (WeakPtr1.IsValid())
	{
		//弱指针如何转换为共享指针
		TSharedPtr<TestA>Sharedptr8(WeakPtr1.Pin());
		
		if (Sharedptr8.IsValid())
		{
			Sharedptr8.Get()->a;
			UE_LOG(LogTemp, Warning, TEXT("Sharedptr8a is %d"), Sharedptr8.Get()->a);
		}
	}
}

 要记得在BeginPlay里面使用
 

void AMySmartPtrActor::BeginPlay()
{
	Super::BeginPlay();
	//TestAFunc();
	//TestBFunc();
	TestCFunc();
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值