UE5 C++(48-3):共享指针的老师讲解的例题。以及 共享指针 TSharedPtr<T, ESPMode> 的源代码

(255)共享指针的老师讲解的例题

++ 通过阅读源码,以上的成员函数的使用,就是自然的。以后附上共享指针的源代码 :

cpp 复制代码
/** TSharedPtr 是一种非侵入式引用计数权威对象指针。
 * TSharedPtr is a non-intrusive reference-counted authoritative object pointer.  This shared pointer
 * will be conditionally thread-safe when the optional Mode template argument is set to ThreadSafe.
 */  //当可选的 Mode 模板参数设置为 ThreadSafe 时,该共享指针将具备条件性线程安全特性。
template< class ObjectType, ESPMode InMode > //ESPMode 是只有俩值的枚举类
class TSharedPtr
{
public:
	using ElementType = ObjectType;
	static constexpr ESPMode Mode = InMode;

	/**
	 * Constructs an empty shared pointer
	 */
	// NOTE: FNullTag parameter is an Unreal extension to standard shared_ptr behavior
	FORCEINLINE TSharedPtr( SharedPointerInternals::FNullTag* = nullptr )
		: Object( nullptr )
		, SharedReferenceCount()
	{
	}

	/** 构造一个所有权属于指定对象的共享指针。
	 * Constructs a shared pointer that owns the specified object.  Note that passing nullptr here will
	 * still create a tracked reference to a nullptr pointer. (Consistent with std::shared_ptr)
	 * 请注意,此处传递 nullptr仍会创建对空指针的跟踪引用。(与 std::shared ptr 保持一致)
	 * @param  InObject  Object this shared pointer to retain a reference to
	 */ // 对象这个共享指针以保留对它的引用
	template <
		typename OtherType,
		typename = decltype(ImplicitConv<ObjectType*>((OtherType*)nullptr))
	>
	FORCEINLINE explicit TSharedPtr( OtherType* InObject )
		: Object( InObject )
		, SharedReferenceCount( SharedPointerInternals::NewDefaultReferenceController< Mode >( InObject ) )
	{
		UE_TSHAREDPTR_STATIC_ASSERT_VALID_MODE(ObjectType, Mode)

		// If the object happens to be derived from TSharedFromThis, the following method
		// will prime the object with a weak pointer to itself.
		SharedPointerInternals::EnableSharedFromThis( this, InObject, InObject );
	}  //如果对象是继承自TSharedFromThis,则以下方法将使用指向自身的弱指针初始化该对象。

	/**
	 * Constructs a shared pointer that owns the specified object.  Note that passing nullptr here will
	 * still create a tracked reference to a nullptr pointer. (Consistent with std::shared_ptr)
	 *
	 * @param  InObject   Object this shared pointer to retain a reference to
	 * @param  InDeleter  Deleter object used to destroy the object when it is no longer referenced.
	 */
	template <
		typename OtherType,
		typename DeleterType,
		typename = decltype(ImplicitConv<ObjectType*>((OtherType*)nullptr))
	>
	FORCEINLINE TSharedPtr( OtherType* InObject, DeleterType&& InDeleter )
		: Object( InObject )
		, SharedReferenceCount( SharedPointerInternals::NewCustomReferenceController< Mode >( InObject, Forward< DeleterType >( InDeleter ) ) )
	{
		UE_TSHAREDPTR_STATIC_ASSERT_VALID_MODE(ObjectType, Mode)

		// If the object happens to be derived from TSharedFromThis, the following method
		// will prime the object with a weak pointer to itself.
		SharedPointerInternals::EnableSharedFromThis( this, InObject, InObject );
	}

	/**
	 * Constructs a shared pointer using a proxy reference to a raw pointer. (See MakeShareable())
	 *
	 * @param  InRawPtrProxy  Proxy raw pointer that contains the object that the new shared pointer will reference
	 */
	// NOTE: The following is an Unreal extension to standard shared_ptr behavior
	template <
		typename OtherType,
		typename = decltype(ImplicitConv<ObjectType*>((OtherType*)nullptr))
	>
	FORCEINLINE TSharedPtr( SharedPointerInternals::TRawPtrProxy< OtherType > const& InRawPtrProxy )
		: Object( InRawPtrProxy.Object )
		, SharedReferenceCount( SharedPointerInternals::NewDefaultReferenceController< Mode >( InRawPtrProxy.Object ) )
	{
		UE_TSHAREDPTR_STATIC_ASSERT_VALID_MODE(ObjectType, Mode)

		// If the object happens to be derived from TSharedFromThis, the following method
		// will prime the object with a weak pointer to itself.
		SharedPointerInternals::EnableSharedFromThis( this, InRawPtrProxy.Object, InRawPtrProxy.Object );
	}

	/**
	 * Constructs a shared pointer using a proxy reference to a raw pointer. (See MakeShareable())
	 *
	 * @param  InRawPtrProxy  Proxy raw pointer that contains the object that the new shared pointer will reference
	 */
	// NOTE: The following is an Unreal extension to standard shared_ptr behavior
	template <
		typename OtherType,
		typename DeleterType,
		typename = decltype(ImplicitConv<ObjectType*>((OtherType*)nullptr))
	>
	FORCEINLINE TSharedPtr( SharedPointerInternals::TRawPtrProxyWithDeleter< OtherType, DeleterType > const& InRawPtrProxy )
		: Object( InRawPtrProxy.Object )
		, SharedReferenceCount( SharedPointerInternals::NewCustomReferenceController< Mode >( InRawPtrProxy.Object, InRawPtrProxy.Deleter ) )
	{
		UE_TSHAREDPTR_STATIC_ASSERT_VALID_MODE(ObjectType, Mode)

		// If the object happens to be derived from TSharedFromThis, the following method
		// will prime the object with a weak pointer to itself.
		SharedPointerInternals::EnableSharedFromThis( this, InRawPtrProxy.Object, InRawPtrProxy.Object );
	}

	/**
	 * Constructs a shared pointer using a proxy reference to a raw pointer. (See MakeShareable())
	 *
	 * @param  InRawPtrProxy  Proxy raw pointer that contains the object that the new shared pointer will reference
	 */
	// NOTE: The following is an Unreal extension to standard shared_ptr behavior
	template <
		typename OtherType,
		typename DeleterType,
		typename = decltype(ImplicitConv<ObjectType*>((OtherType*)nullptr))
	>
	FORCEINLINE TSharedPtr( SharedPointerInternals::TRawPtrProxyWithDeleter< OtherType, DeleterType >&& InRawPtrProxy )
		: Object( InRawPtrProxy.Object )
		, SharedReferenceCount( SharedPointerInternals::NewCustomReferenceController< Mode >( InRawPtrProxy.Object, MoveTemp( InRawPtrProxy.Deleter ) ) )
	{
		UE_TSHAREDPTR_STATIC_ASSERT_VALID_MODE(ObjectType, Mode)

		// If the object happens to be derived from TSharedFromThis, the following method
		// will prime the object with a weak pointer to itself.
		SharedPointerInternals::EnableSharedFromThis( this, InRawPtrProxy.Object, InRawPtrProxy.Object );
	}

	/**
	 * Constructs a shared pointer as a shared reference to an existing shared pointer's object.
	 * This constructor is needed so that we can implicitly upcast to base classes.
	 *
	 * @param  InSharedPtr  The shared pointer whose object we should create an additional reference to
	 */
	template <
		typename OtherType,
		typename = decltype(ImplicitConv<ObjectType*>((OtherType*)nullptr))
	>
	FORCEINLINE TSharedPtr( TSharedPtr< OtherType, Mode > const& InSharedPtr )
		: Object( InSharedPtr.Object )
		, SharedReferenceCount( InSharedPtr.SharedReferenceCount )
	{
	}

	FORCEINLINE TSharedPtr( TSharedPtr const& InSharedPtr )
		: Object( InSharedPtr.Object )
		, SharedReferenceCount( InSharedPtr.SharedReferenceCount )
	{
	}

	FORCEINLINE TSharedPtr( TSharedPtr&& InSharedPtr )
		: Object( InSharedPtr.Object )
		, SharedReferenceCount( MoveTemp(InSharedPtr.SharedReferenceCount) )
	{
		InSharedPtr.Object = nullptr;
	}

	/**
	 * Implicitly converts a shared reference to a shared pointer, adding a reference to the object.
	 * NOTE: We allow an implicit conversion from TSharedRef to TSharedPtr because it's always a safe conversion.
	 *
	 * @param  InSharedRef  The shared reference that will be converted to a shared pointer
	 */
	// NOTE: The following is an Unreal extension to standard shared_ptr behavior
	template <
		typename OtherType,
		typename = decltype(ImplicitConv<ObjectType*>((OtherType*)nullptr))
	>
	FORCEINLINE TSharedPtr( TSharedRef< OtherType, Mode > const& InSharedRef )
		: Object( InSharedRef.Object )
		, SharedReferenceCount( InSharedRef.SharedReferenceCount )
	{
		// There is no rvalue overload of this constructor, because 'stealing' the pointer from a
		// TSharedRef would leave it as null, which would invalidate its invariant.
	}

	/**
	 * Special constructor used internally to statically cast one shared pointer type to another.  You
	 * should never call this constructor directly.  Instead, use the StaticCastSharedPtr() function.
	 * This constructor creates a shared pointer as a shared reference to an existing shared pointer after
	 * statically casting that pointer's object.  This constructor is needed for static casts.
	 *
	 * @param  InSharedPtr  The shared pointer whose object we should create an additional reference to
	 */
	template <typename OtherType>
	FORCEINLINE TSharedPtr( TSharedPtr< OtherType, Mode > const& InSharedPtr, SharedPointerInternals::FStaticCastTag )
		: Object( static_cast< ObjectType* >( InSharedPtr.Object ) )
		, SharedReferenceCount( InSharedPtr.SharedReferenceCount )
	{
	}
	
	/**
	 * Special constructor used internally to cast a 'const' shared pointer a 'mutable' pointer.  You
	 * should never call this constructor directly.  Instead, use the ConstCastSharedPtr() function.
	 * This constructor creates a shared pointer as a shared reference to an existing shared pointer after
	 * const casting that pointer's object.  This constructor is needed for const casts.
	 *
	 * @param  InSharedPtr  The shared pointer whose object we should create an additional reference to
	 */
	template <typename OtherType>
	FORCEINLINE TSharedPtr( TSharedPtr< OtherType, Mode > const& InSharedPtr, SharedPointerInternals::FConstCastTag )
		: Object( const_cast< ObjectType* >( InSharedPtr.Object ) )
		, SharedReferenceCount( InSharedPtr.SharedReferenceCount )
	{
	}

	/**
	 * Aliasing constructor used to create a shared pointer which shares its reference count with
	 * another shared object, but pointing to a different object, typically a subobject.
	 *
	 * @param  OtherSharedPtr  The shared pointer whose reference count should be shared.
	 * @param  InObject  The object pointer to use (instead of the incoming shared pointer's object)
	 */
	template <typename OtherType>
	FORCEINLINE TSharedPtr( TSharedPtr< OtherType, Mode > const& OtherSharedPtr, ObjectType* InObject )
		: Object( InObject )
		, SharedReferenceCount( OtherSharedPtr.SharedReferenceCount )
	{
	}

	/**
	 * Aliasing constructor used to create a shared pointer which shares its reference count with
	 * another shared object, but pointing to a different object, typically a subobject.
	 *
	 * @param  OtherSharedPtr  The shared pointer whose reference count should be shared.
	 * @param  InObject  The object pointer to use (instead of the incoming shared pointer's object)
	 */
	template <typename OtherType>
	FORCEINLINE TSharedPtr( TSharedPtr< OtherType, Mode >&& OtherSharedPtr, ObjectType* InObject )
		: Object( InObject )
		, SharedReferenceCount( MoveTemp(OtherSharedPtr.SharedReferenceCount) )
	{
		OtherSharedPtr.Object = nullptr;
	}

	/**
	 * Aliasing constructor used to create a shared pointer which shares its reference count with
	 * another shared object, but pointing to a different object, typically a subobject.
	 *
	 * @param  OtherSharedRef  The shared reference whose reference count should be shared.
	 * @param  InObject  The object pointer to use (instead of the incoming shared pointer's object)
	 */
	template <typename OtherType>
	FORCEINLINE TSharedPtr( TSharedRef< OtherType, Mode > const& OtherSharedRef, ObjectType* InObject )
		: Object( InObject )
		, SharedReferenceCount( OtherSharedRef.SharedReferenceCount )
	{
	}

	/** 对空指针的赋值。当前由该共享指针引用的对象将不再被引用,并且如果没有任何其他引用者,将会被删除。
	 * Assignment to a nullptr pointer.  The object currently referenced by this shared pointer will no longer be
	 * referenced and will be deleted if there are no other referencers.
	 */
	// NOTE: The following is an Unreal extension to standard shared_ptr behavior
	FORCEINLINE TSharedPtr& operator=( SharedPointerInternals::FNullTag* )
	{
		Reset();
		return *this;
	}

	/**
	 * Assignment operator replaces this shared pointer with the specified shared pointer.  The object
	 * currently referenced by this shared pointer will no longer be referenced and will be deleted if
	 * there are no other referencers.
	 *
	 * @param  InSharedPtr  Shared pointer to replace with
	 */
	FORCEINLINE TSharedPtr& operator=( TSharedPtr const& InSharedPtr )
	{
		TSharedPtr Temp = InSharedPtr;
		::Swap(Temp, *this);
		return *this;
	}

	FORCEINLINE TSharedPtr& operator=( TSharedPtr&& InSharedPtr )
	{
		if (this != &InSharedPtr)
		{
			Object = InSharedPtr.Object;
			InSharedPtr.Object = nullptr;
			SharedReferenceCount = MoveTemp(InSharedPtr.SharedReferenceCount);
		}
		return *this;
	}

	/**
	 * Assignment operator replaces this shared pointer with the specified shared pointer.  The object
	 * currently referenced by this shared pointer will no longer be referenced and will be deleted if
	 * there are no other referencers.
	 *
	 * @param  InRawPtrProxy  Proxy object used to assign the object (see MakeShareable helper function)
	 */
	// NOTE: The following is an Unreal extension to standard shared_ptr behavior
	template <
		typename OtherType,
		typename = decltype(ImplicitConv<ObjectType*>((OtherType*)nullptr))
	>
	FORCEINLINE TSharedPtr& operator=( SharedPointerInternals::TRawPtrProxy< OtherType > const& InRawPtrProxy )
	{
		*this = TSharedPtr< ObjectType, Mode >( InRawPtrProxy );
		return *this;
	}

	/**
	 * Assignment operator replaces this shared pointer with the specified shared pointer.  The object
	 * currently referenced by this shared pointer will no longer be referenced and will be deleted if
	 * there are no other referencers.
	 *
	 * @param  InRawPtrProxy  Proxy object used to assign the object (see MakeShareable helper function)
	 */
	// NOTE: The following is an Unreal extension to standard shared_ptr behavior
	template <
		typename OtherType,
		typename DeleterType,
		typename = decltype(ImplicitConv<ObjectType*>((OtherType*)nullptr))
	>
	FORCEINLINE TSharedPtr& operator=( SharedPointerInternals::TRawPtrProxyWithDeleter< OtherType, DeleterType > const& InRawPtrProxy )
	{
		*this = TSharedPtr< ObjectType, Mode >( InRawPtrProxy );
		return *this;
	}

	/**
	 * Assignment operator replaces this shared pointer with the specified shared pointer.  The object
	 * currently referenced by this shared pointer will no longer be referenced and will be deleted if
	 * there are no other referencers.
	 *
	 * @param  InRawPtrProxy  Proxy object used to assign the object (see MakeShareable helper function)
	 */
	// NOTE: The following is an Unreal extension to standard shared_ptr behavior
	template <
		typename OtherType,
		typename DeleterType,
		typename = decltype(ImplicitConv<ObjectType*>((OtherType*)nullptr))
	>
	FORCEINLINE TSharedPtr& operator=( SharedPointerInternals::TRawPtrProxyWithDeleter< OtherType, DeleterType >&& InRawPtrProxy )
	{
		*this = TSharedPtr< ObjectType, Mode >( MoveTemp( InRawPtrProxy ) );
		return *this;
	}

	/** 将共享指针转换为共享引用。该指针必须有效,否则会触发断言。
	 * Converts a shared pointer to a shared reference.  The pointer *must* be valid or an assertion will trigger.
	 *
	 * @return  Reference to the object
	 */ //注意:以下是对标准shared_ptr行为的Unreal扩展
	// NOTE: The following is an Unreal extension to standard shared_ptr behavior
	[[nodiscard]] FORCEINLINE TSharedRef< ObjectType, Mode > ToSharedRef() const&
	{
		// If this assert goes off, it means a shared reference was created from a shared pointer that was nullptr.
		// Shared references are never allowed to be null.  Consider using TSharedPtr instead.
		check( IsValid() );
		return TSharedRef< ObjectType, Mode >( *this );
	}

	/**
	 * Converts a shared pointer to a shared reference.  The pointer *must* be valid or an assertion will trigger.
	 *
	 * @return  Reference to the object
	 */
	 // NOTE: The following is an Unreal extension to standard shared_ptr behavior
	[[nodiscard]] FORCEINLINE TSharedRef< ObjectType, Mode > ToSharedRef() &&
	{
		// If this assert goes off, it means a shared reference was created from a shared pointer that was nullptr.
		// Shared references are never allowed to be null.  Consider using TSharedPtr instead.
		check( IsValid() );
		return TSharedRef< ObjectType, Mode >( MoveTemp( *this ) );
	}

	/**
	 * Converts a shared pointer to a weak ptr.
	 *
	 * @return  Weak pointer to the object
	 */
	[[nodiscard]] FORCEINLINE TWeakPtr<ObjectType, Mode> ToWeakPtr() const
	{
		return TWeakPtr<ObjectType, Mode>(*this);
	}

	/**
	 * Returns the object referenced by this pointer, or nullptr if no object is reference
	 *
	 * @return  The object owned by this shared pointer, or nullptr
	 */
	[[nodiscard]] FORCEINLINE ObjectType* Get() const
	{
		return Object;
	}

	/**
	 * Checks to see if this shared pointer is actually pointing to an object
	 *
	 * @return  True if the shared pointer is valid and can be dereferenced
	 */
	[[nodiscard]] FORCEINLINE explicit operator bool() const
	{
		return Object != nullptr;
	}

	/**
	 * Checks to see if this shared pointer is actually pointing to an object
	 *
	 * @return  True if the shared pointer is valid and can be dereferenced
	 */
	[[nodiscard]] FORCEINLINE const bool IsValid() const
	{
		return Object != nullptr;
	}

	/**
	 * Dereference operator returns a reference to the object this shared pointer points to
	 *
	 * @return  Reference to the object
	 */
	[[nodiscard]] FORCEINLINE decltype(auto) operator*() const
	{
		check( IsValid() );
		return *Object;
	}

	/**
	 * Arrow operator returns a pointer to the object this shared pointer references
	 *
	 * @return  Returns a pointer to the object referenced by this shared pointer
	 */
	[[nodiscard]] FORCEINLINE ObjectType* operator->() const
	{
		check( IsValid() );
		return Object;
	}

	/**
	 * Resets this shared pointer, removing a reference to the object.  If there are no other shared
	 * references to the object then it will be destroyed.
	 */
	FORCEINLINE void Reset()
	{
 		*this = TSharedPtr< ObjectType, Mode >();
	}

	/**
	 * Returns the number of shared references to this object (including this reference.)
	 * IMPORTANT: Not necessarily fast!  Should only be used for debugging purposes!
	 *
	 * @return  Number of shared references to the object (including this reference.)
	 */
	[[nodiscard]] FORCEINLINE int32 GetSharedReferenceCount() const
	{
		return SharedReferenceCount.GetSharedReferenceCount();
	}

	/** 如果这是对该对象的唯一共享引用,则返回true。请注意,可能仍有未清除的弱引用残留。
	 * Returns true if this is the only shared reference to this object.  
	 * Note that there may be outstanding weak references left.
	 * IMPORTANT: Not necessarily fast!  Should only be used for debugging purposes!
	 *
	 * @return  True if there is only one shared reference to the object, and this is it!
	 */
	[[nodiscard]] FORCEINLINE bool IsUnique() const
	{
		return SharedReferenceCount.IsUnique();
	}

private:
	// 从弱指针构建出一个共享指针,从而让你能够访问该对象(如果它尚未过期的话)。
	/** 请记住,如果对该对象不再存在任何共享引用,则该共享指针将失效。
	 * Constructs a shared pointer from a weak pointer, allowing you to access the object (if it
	 * hasn't expired yet.)  Remember, if there are no more shared references to the object, 
	 * the shared pointer will not be valid.  You should always check to make sure this shared
	 * pointer is valid before trying to dereference the shared pointer!
	 * 在尝试解引用共享指针之前,你应始终进行检查以确保该共享指针的有效性!
	 * NOTE: This constructor is private to force users to be explicit when converting a weak
	 *       pointer to a shared pointer.  Use the weak pointer's Pin() method instead!
	 */ //此构造函数为私有,强制用户在将弱指针转换为共享指针时必须明确操作。请改用弱指针的Pin()方法!
	template <
		typename OtherType,
		typename = decltype(ImplicitConv<ObjectType*>((OtherType*)nullptr))
	>
	FORCEINLINE explicit TSharedPtr( TWeakPtr< OtherType, Mode > const& InWeakPtr )
		: Object( nullptr )
		, SharedReferenceCount( InWeakPtr.WeakReferenceCount )
	{   //检查共享引用是否已成功从弱引用创建。只有在我们拥有有效的共享引用时,才会缓存对象的指针。
		// Check that the shared reference was created from the weak reference successfully.  
		// We'll only cache a pointer to the object if we have a valid shared reference.
		if( SharedReferenceCount.IsValid() )
		{
			Object = InWeakPtr.Object;
		}
	}

	/**
	 * Constructs a shared pointer from a weak pointer, allowing you to access the object (if it
	 * hasn't expired yet.)  Remember, if there are no more shared references to the object, the
	 * shared pointer will not be valid.  You should always check to make sure this shared
	 * pointer is valid before trying to dereference the shared pointer!
	 *
	 * NOTE: This constructor is private to force users to be explicit when converting a weak
	 *       pointer to a shared pointer.  Use the weak pointer's Pin() method instead!
	 */
	template <
		typename OtherType
		UE_REQUIRES(std::is_convertible_v<OtherType*, ObjectType*>)
	>
	FORCEINLINE explicit TSharedPtr(TWeakPtr< OtherType, Mode >&& InWeakPtr)
		: Object(nullptr)
		, SharedReferenceCount( MoveTemp( InWeakPtr.WeakReferenceCount ) )
	{
		// Check that the shared reference was created from the weak reference successfully.  We'll only
		// cache a pointer to the object if we have a valid shared reference.
		if (SharedReferenceCount.IsValid())
		{
			Object = InWeakPtr.Object;
			InWeakPtr.Object = nullptr;
		}
	}

	// We declare ourselves as a friend (templated using OtherType) so we can access members as needed
	template< class OtherType, ESPMode OtherMode > friend class TSharedPtr;

	// Declare other smart pointer types as friends as needed
	template< class OtherType, ESPMode OtherMode > friend class TSharedRef;
	template< class OtherType, ESPMode OtherMode > friend class TWeakPtr;
	template< class OtherType, ESPMode OtherMode > friend class TSharedFromThis;

private:

	/** The object we're holding a reference to.  Can be nullptr. */
	ObjectType* Object;
	//此对象的引用计数器接口。请注意,实际的引用控制器对象由所有指向该对象的共享和弱指针共享。
	/** Interface to the reference counter for this object.  Note that the actual reference
		controller object is shared by all shared and weak pointers that refer to the object */
	SharedPointerInternals::FSharedReferencer< Mode > SharedReferenceCount;
}; //完结 template< class ObjectType, ESPMode InMode > class TSharedPtr

(256)

谢谢

相关推荐
暮志未晚Webgl1 天前
UE5Niagara粒子系统性能优化
ue5
努力的小钟2 天前
UObject创建系统深度分析
ue5
速冻鱼Kiel2 天前
Lyra的相机系统
笔记·ue5·游戏引擎·虚幻
暮志未晚Webgl2 天前
UE5模型面数优化
ue5
zhangzhangkeji2 天前
UE5 C++(45):射线检测多物体的的按通道与按对象类型 LineTraceMultiByObjectType
ue5
成都渲染101云渲染66662 天前
5090 显卡云端上线!Blender / Maya / UE5 渲染速度再提升,云渲染成主流选择
ue5·blender·maya
一个响当当的名号3 天前
lectrue5 存储模型和压缩
ue5
zhangzhangkeji3 天前
UE5 C++(44-4):对比一下蓝图中的射线检测节点,源代码,按通道与按对象类型
ue5
暮志未晚Webgl4 天前
UE使用内置功能查看性能
ue5