mirror of https://github.com/axmolengine/axmol.git
RefPtr<T> - add move semantics
Add support for move semantics to the RefPtr<T> class. Implement a move constructor and a move assignment operator.
This commit is contained in:
parent
440a0adcde
commit
14b210a082
|
@ -82,10 +82,19 @@ NS_CC_BEGIN
|
|||
template <typename T> class RefPtr
|
||||
{
|
||||
public:
|
||||
RefPtr()
|
||||
: _ptr(nullptr)
|
||||
|
||||
inline RefPtr()
|
||||
:
|
||||
_ptr(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
inline RefPtr(RefPtr && other)
|
||||
{
|
||||
_ptr = other._ptr;
|
||||
other._ptr = nullptr;
|
||||
}
|
||||
|
||||
inline RefPtr(T * ptr)
|
||||
:
|
||||
|
@ -113,7 +122,7 @@ public:
|
|||
CC_REF_PTR_SAFE_RELEASE_NULL(_ptr);
|
||||
}
|
||||
|
||||
inline RefPtr & operator = (const RefPtr<T> & other)
|
||||
inline RefPtr<T> & operator = (const RefPtr<T> & other)
|
||||
{
|
||||
if (other._ptr != _ptr)
|
||||
{
|
||||
|
@ -125,13 +134,19 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline RefPtr & operator = (std::nullptr_t other)
|
||||
inline RefPtr<T> & operator = (RefPtr<T> && other)
|
||||
{
|
||||
CC_REF_PTR_SAFE_RELEASE_NULL(_ptr);
|
||||
if (&other != this)
|
||||
{
|
||||
CC_REF_PTR_SAFE_RELEASE(_ptr);
|
||||
_ptr = other._ptr;
|
||||
other._ptr = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline RefPtr & operator = (T * other)
|
||||
inline RefPtr<T> & operator = (T * other)
|
||||
{
|
||||
if (other != _ptr)
|
||||
{
|
||||
|
@ -143,6 +158,12 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline RefPtr<T> & operator = (std::nullptr_t other)
|
||||
{
|
||||
CC_REF_PTR_SAFE_RELEASE_NULL(_ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Note: using reinterpret_cast<> instead of static_cast<> here because it doesn't require type info.
|
||||
// Since we verify the correct type cast at compile time on construction/assign we don't need to know the type info
|
||||
// here. Not needing the type info here enables us to use these operations in inline functions in header files when
|
||||
|
|
|
@ -279,6 +279,41 @@ void RefPtrTest::onEnter()
|
|||
CC_ASSERT(false == (ref1 <= ref2));
|
||||
CC_ASSERT(true == (ref1 >= ref2));
|
||||
}
|
||||
|
||||
// TEST(moveConstructor)
|
||||
{
|
||||
auto someFunc = []() -> RefPtr<__String>
|
||||
{
|
||||
return __String::create("Hello world!");
|
||||
};
|
||||
|
||||
// Note: std::move will turn the rvalue into an rvalue reference and thus cause the move constructor to be invoked.
|
||||
// Have to use this because the compiler will try and optimize how we handle the return value otherwise and skip the move constructor.
|
||||
RefPtr<__String> theString(std::move(someFunc()));
|
||||
CC_ASSERT(theString->getReferenceCount() == 2);
|
||||
CC_ASSERT(theString->compare("Hello world!") == 0);
|
||||
|
||||
__String * theStringPtr = theString;
|
||||
theString.reset();
|
||||
CC_ASSERT(theStringPtr->getReferenceCount() == 1);
|
||||
CC_ASSERT(theStringPtr->compare("Hello world!") == 0);
|
||||
}
|
||||
|
||||
// TEST(moveAssignmentOperator)
|
||||
{
|
||||
auto someFunc = []() -> RefPtr<__String>
|
||||
{
|
||||
return __String::create("Hello world!");
|
||||
};
|
||||
|
||||
RefPtr<__String> theString(someFunc());
|
||||
CC_ASSERT(theString->getReferenceCount() == 2);
|
||||
CC_ASSERT(theString->compare("Hello world!") == 0);
|
||||
|
||||
theString = someFunc(); // No need to use std::move here, compiler should figure out that move semantics are appropriate for this statement.
|
||||
CC_ASSERT(theString->getReferenceCount() == 2);
|
||||
CC_ASSERT(theString->compare("Hello world!") == 0);
|
||||
}
|
||||
}
|
||||
|
||||
std::string RefPtrTest::subtitle() const
|
||||
|
|
Loading…
Reference in New Issue