概念
共享指针(Shared Pointers) 是指既健壮、又能为空指针的智能指针。共享指针沿袭了普通智能指针的所有优点,它能避免出现内存泄漏、悬挂指针,还能避免指针指向未初始化的内存。但它们还有一些其他特点,例如:
- 共享所有权(Shared Ownership): 引用计数支持多个共享指针,以确保它们引用的数据对象永远不被删除,前提是它们中的任意一个仍指向数据对象。
- 自动失效(Automatic Invalidation): 你可安全引用易变对象,无需担心出现悬挂指针。
- 弱引用: 弱指针可中断引用循环。
- 意向指示(Indication of Intent): 区分拥有者(参见共享引用)和观察者,并提供不可为空的引用。
共享指针有一些值得注意的基本特性,包括:
- 语法非常健壮
- 非侵入式(但能反射)
- 线程安全(视情况而定)
性能佳,占用内存少
共享引用 是一类强大且不可为空的 智能指针,其被用于引擎的 Uobject 系统外的数据对象。此意味无法重置共享引用、向其指定空对象,或创建空白引用。因此共享引用固定包含有效对象,甚至未拥有 IsValid 方法。在共享引用和 [共享指针](Shared Pointers) 间选择时,除非需要空白或可为空的对象,否则共享引用为优先选项。如需可能空白或可为空的引用,则应使用共享指针。
注意:与标准的C++引用不同,可在创建后将共享引用重新指定到另一对象。依我看,本质来说,引用是一种特殊的指针。
线程安全
线程安全的声明如下,不写则为不安全
TSharedPtr<NormalClass,ESPMode::ThreadSafe> NormalSharedPtr(new NormalClass(TEXT( FUNCTION )));
测试代码
头文件
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"#include "UObject/NoExportTypes.h"#include "MyObject.generated.h"/****///用宏声明2个参数的委托,返回值int32DECLARE_DELEGATE_RetVal_TwoParams(int32, FTestDelegateTwoparamsRetVal, float, const FString&);UCLASS(Blueprintable)class TESTCPP_API UMyObject : public UObject{GENERATED_BODY()public:UMyObject();UPROPERTY(BlueprintReadWrite)float value = 15;UFUNCTION(BlueprintCallable)void myfunction();UFUNCTION(BlueprintCallable)int32 testDelegatefuction(float a, const FString& s);//声明被委托的函数UFUNCTION(BlueprintCallable)void testfuntion();UFUNCTION(BlueprintCallable)void testRef();UFUNCTION(BlueprintCallable)void tranform();FTestDelegateTwoparamsRetVal myDelegate;//声明一个委托对象};class Fmyclass {public:Fmyclass() { UE_LOG(LogTemp, Warning, TEXT("Hellow Fmyclass")); }void testFun() { UE_LOG(LogTemp, Warning, TEXT("Test Fmyclass")); }~Fmyclass() { UE_LOG(LogTemp, Warning, TEXT("Dead Fmyclass")); };};
实现
// Fill out your copyright notice in the Description page of Project Settings.#include <string.h>#include "MyObject.h"UMyObject::UMyObject() {}void UMyObject::myfunction(){UE_LOG(LogTemp, Warning, TEXT("Hellow World"));GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, FString::Printf(TEXT("value = %d"), value));//实现绑定myDelegate.BindUObject(this, &UMyObject::testDelegatefuction);//判断是否绑定成功,避免崩溃if (myDelegate.IsBound())myDelegate.Execute(23, "Hi");}int32 UMyObject::testDelegatefuction(float a, const FString& s){return int32(a);}void UMyObject::testfuntion(){//创建一个共享指针对象TSharedPtr<Fmyclass> testptr = MakeShareable(new Fmyclass());//判断有效性,并调用成员函数if (testptr.IsValid()){testptr->testFun();}//获取指针计数int32 count = testptr.GetSharedReferenceCount();UE_LOG(LogTemp, Warning, TEXT("Count=%d"), count);//手动解引用,不写也可以,离开本作用域消亡testptr.Reset();}void UMyObject::testRef(){//创建共享引用,两种写法TSharedRef<Fmyclass> testref = MakeShareable(new Fmyclass);TSharedRef<Fmyclass> testref2(testref);//获取引用计数int32 count = testref.GetSharedReferenceCount();//返回CPP类对象testref.Get();//调用成员函数testref2->testFun();//判断是唯一引用if (testref.IsUnique()){UE_LOG(LogTemp, Warning, TEXT("isUniqueRef"));}}void UMyObject::tranform(){// 共享引用转化成共享指针TSharedRef<Fmyclass> TestRef = MakeShareable(new Fmyclass);TSharedPtr<Fmyclass> TestPtr = TestRef;//共享指针转化成共享引用TSharedPtr<Fmyclass>TestPtr2 = MakeShareable(new Fmyclass);TSharedRef<Fmyclass>TestRef2 = TestPtr2.ToSharedRef();}
测试结果

