#include "VoxelSharedPtr.h"
/Engine/Source/Runtime/Core/Public/Templates/SharedPointer.h 里面有UE智能指针详细用法,还有解释了为什么要自己造轮子
/* Why did we write our own Unreal shared pointer instead of using available alternatives?
*
* - std::shared_ptr (and even tr1::shared_ptr) is not yet available on all platforms
* - Allows for a more consistent implementation on all compilers and platforms
* - Can work seamlessly with other Unreal containers and types
* - Better control over platform specifics, including threading and optimizations
* - We want thread-safety features to be optional (for performance)
* - We've added our own improvements (MakeShareable, assign to nullptr, etc.)
* - Exceptions were not needed nor desired in our implementation
* - We wanted more control over performance (inlining, memory, use of virtuals, etc.)
* - Potentially easier to debug (liberal code comments, etc.)
* - Prefer not to introduce new third party dependencies when not needed
*/
ESPMode::ThreadSafe 相对于 ESPMode::NotThreadSafe 和自动平台适应 ESPMode::Fast
C++标准库的 std::shared_ptr 只是引用计数安全, 这难免让我对SharedPointer源码有了一点期待
//VoxelSharedPtr.h
template<typename T>
using TVoxelSharedRef = TSharedRef<T, ESPMode::ThreadSafe>;
我们顺着插件这条到SharedPointerInternal.h挖一下得到
//SharedPointerInternal.h
template< class ObjectType, ESPMode Mode = ESPMode::Fast > class TSharedRef;
template< class ObjectType, ESPMode Mode = ESPMode::Fast > class TSharedPtr;
template< class ObjectType, ESPMode Mode = ESPMode::Fast > class TWeakPtr;
template< class ObjectType, ESPMode Mode = ESPMode::Fast > class TSharedFromThis;
表明UE4和UE5的智能指针默认就算不安全的
然后继续挖回到SharedPointer.h看到
//SharedPointer.h
template< class ObjectType, ESPMode Mode >
class TSharedRef
{
public:
using ElementType = ObjectType;
// NOTE: TSharedRef has no default constructor as it does not support empty references. You must
// initialize your TSharedRef to a valid object at construction time.
/**
* Constructs a shared reference that owns the specified object. Must not be nullptr.
*
* @param InObject Object this shared reference to retain a reference to
*/
template <
typename OtherType,
typename = decltype(ImplicitConv<ObjectType*>((OtherType*)nullptr))
>
FORCEINLINE explicit TSharedRef( OtherType* InObject )
: Object( InObject )
, SharedReferenceCount( SharedPointerInternals::NewDefaultReferenceController( InObject ) )
{
UE_TSHAREDPTR_STATIC_ASSERT_VALID_MODE(ObjectType, Mode)
Init(InObject);
}
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;
}
然后再顺着ESPMode挖得到
// TSharedPtr of one mode to a type which has a TSharedFromThis only of another mode is illegal.
// A type which does not inherit TSharedFromThis at all is ok.
// We only check this inside the constructor because we don't necessarily have the full type of T when we declare a TSharedPtr<T>.
#define UE_TSHAREDPTR_STATIC_ASSERT_VALID_MODE(ObjectType, Mode) \
enum \
{ \
ObjectTypeHasSameModeSharedFromThis = TPointerIsConvertibleFromTo<ObjectType, TSharedFromThis<ObjectType, Mode>>::Value, \
ObjectTypeHasOppositeModeSharedFromThis = TPointerIsConvertibleFromTo<ObjectType, TSharedFromThis<ObjectType, (Mode == ESPMode::NotThreadSafe) ? ESPMode::ThreadSafe : ESPMode::NotThreadSafe>>::Value \
}; \
static_assert(ObjectTypeHasSameModeSharedFromThis || !ObjectTypeHasOppositeModeSharedFromThis, "You cannot use a TSharedPtr of one mode with a type which inherits TSharedFromThis of another mode.");
这里判断class如果是TSharedFromThis 的继承类就不能修改线程安全状态
我的初步理解是, 这样会报错, 但问题是判断过程, 应该是编译器负责的, 我很好奇,最后讲讲
//Fake Code
#include "CoreMinimal.h"
class SomeClass:TSharedFromThis<OwnClass, ESPMode::