UE4智能指针的相关使用事项

23 篇文章 12 订阅


UE4智能指针TSharedPtr的几种初始化方式

UE4智能指针TSharedRef的几种初始化方式

以上两篇文章里面简单介绍了TSharedPtr和TSharedRef的构造方式,因为TWeakPtr的构造相对简单,所以就不单独开一篇文章来介绍了。 

在介绍UE智能指针的使用场景之前,有必要对TWeakPtr进行一下特殊介绍,因为TWeakPtr的相关操作,都不是通过它本身进行的,必须要借助Pin函数得到TSharedPtr,通过这个TSharedPtr进行操作。C++11提供的weak_ptr,也要通过lock函数得到shared_ptr,再用shared_ptr操作。Why?因为如果直接使用weak_ptr,那如果在使用期间目标被销毁了,weak_ptr继续操作,就会导致崩溃。而先转成shared_ptr,就会先强制引用,从而目标不会被销毁,操作就会变得安全。

针对智能指针,主要有以下操作场景。

1、判断智能指针指向的目标是否有效。

调用函数IsValid,TSharedPtr TSharedRefr都实现了这个函数。

2、操作目标指针,我们可以像使用原生指针一样操作智能指针

			
struct FSharedTest
{
	bool bFoo;
};
TSharedPtr< FSharedTest, Mode > SharedArray( new FSharedTest() );

// TSharedPtr使用起来像原生指针一样			
SharedArray->bFoo = true;

 TSharedPtr TSharedRef都可以这么操作。所以虽然TSharedRef起名像是智能引用,但使用起来就是个指针。

3、取消强引用。

对于TSharedPtr而言,变量出了生命域后,会自动将强引用计数-1,但如果想手动取消的话,可以调用TSharedPtr::Reset函数。

对于TSharedRef而言,没有Reset函数!只能等变量生命结束后,自动减少引用计数!原因还是在于TSharedRef的定位为一个始终有效的智能指针,如果手动Reset,那不变成无效了嘛!

4、判断两个智能指针是否相等。直接使用==操作两个智能指针即可,如果两个指针引用的Object相同,则返回true,否则返回false。下图可以看出,UE4重载了很多方法,用来进行指针间的相等判断。

 5、解引用。解引用得到的是一个引用类型。

struct FSharedTest
{
    bool bFoo;
};
TSharedPtr< FSharedTest, Mode > SharedArray( new FSharedTest() );
//解引用得到的类型是引用,而不是值!
( *SharedArray ).bFoo = false;

6、指针转换,Cast。使用StaticCast进行downcast,使用CastCast去除const属性。

// Test casting
class FBase
{
	bool bFoo;
};
class FDerived: public FBase
{ };

{
	//父向子Cast,用StaticCast
	TSharedPtr< FBase, Mode > DerivedAsBasePtr( new FDerived() );
	TSharedPtr< FDerived, Mode > DerivedPtr( StaticCastSharedPtr< FDerived >( DerivedAsBasePtr ) );
}

{
	//子向父Cast,不需要!直接赋值即可!
	TSharedPtr< FDerived, Mode > DerivedPtr( new FDerived() );
	TSharedPtr< FBase, Mode > BasePtr( DerivedPtr );
}


TSharedPtr< const float, Mode > FloatPtrB( new float( 2.0f ) );
TWeakPtr< float, Mode > WeakFloat;
//使用ConstCast去除Const属性
WeakFloat = ConstCastSharedPtr< float >( FloatPtrB );

cast也有几个函数版本,分别用于处理TSharedPtr TSharedRef

7、对外传递引用。需要继承TSharedFromThis,AsShared返回声明的类型,SharedThis返回实际类型。关于这两个函数的区别,官网介绍代码如下

class FRegistryObject;
class FMyBaseClass: public TSharedFromThis<FMyBaseClass>
{
    virtual void RegisterAsBaseClass(FRegistryObject* RegistryObject)
    {
        // Access a shared reference to 'this'.
        // We are directly inherited from <TSharedFromThis> , so AsShared() and SharedThis(this) return the same type.
        TSharedRef<FMyBaseClass> ThisAsSharedRef = AsShared();
        // RegistryObject expects a TSharedRef<FMyBaseClass>, or a TSharedPtr<FMyBaseClass>. TSharedRef can implicitly be converted to a TSharedPtr.
        RegistryObject->Register(ThisAsSharedRef);
    }
};
class FMyDerivedClass : public FMyBaseClass
{
    virtual void Register(FRegistryObject* RegistryObject) override
    {
        // We are not directly inherited from TSharedFromThis<>, so AsShared() and SharedThis(this) return different types.
        // AsShared() will return the type originally specified in TSharedFromThis<> - TSharedRef<FMyBaseClass> in this example.
        // SharedThis(this) will return a TSharedRef with the type of 'this' - TSharedRef<FMyDerivedClass> in this example.
        // The SharedThis() function is only available in the same scope as the 'this' pointer.
        TSharedRef<FMyDerivedClass> AsSharedRef = SharedThis(this);
        // RegistryObject will accept a TSharedRef<FMyDerivedClass> because FMyDerivedClass is a type of FMyBaseClass.
        RegistryObject->Register(ThisAsSharedRef);
    }
};
class FRegistryObject
{
    // This function will accept a TSharedRef or TSharedPtr to FMyBaseClass or any of its children.
    void Register(TSharedRef<FMyBaseClass>);
};

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值