(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)
谢谢