##Overall
Overall
##Code Review
Code Review
###Constructing from object!
Constructing from object!
###Use member initializing list.
Use member initializing list.
###Member variable Names
Member variable Names
###NoExcept
NoExcept
###Leak in assignment
Leak in assignment
###Checking for this pessimization
Checking for this pessimization
Summary
###Summary GoodGood first try but still lots of issues.
namespace ThorsAnvil
{
template<typename T>
class UP
{
T* data;
public:
UP()
: data(nullptr)
{}
// Explicit constructor
explicit UP(T* data)
: data(data)
{}
~UP()
{
delete data;
}
// Constructor/Assignment that binds to nullptr
// This makes usage with nullptr cleaner
UP(std::nullptr_t)
: data(nullptr)
{}
UP& operator=(std::nullptr_t)
{
reset();
return *this;
}
// Constructor/Assignment that allows move semantics
UP(UP&& moving) noexcept
: data(nullptr)
{
moving.swap(*this);
// In the comments it was pointed out that this
// does not match the implementation of std::unique_ptr
// I am going to leave mine the same. But
// the the standard provides some extra guarantees
// and probably a more intuitive usage.
}
UP& operator=(UP&& moving) noexcept
{
moving.swap(*this);
return *this;
// See move constructor.
}
// Constructor/Assignment for use with types derived from T
template<typename U>
UP(UP<U>&& moving)
{
UP<T> tmp(moving.release());
tmp.swap(*this);
}
template<typename U>
UP& operator=(UP<U>&& moving)
{
UP<T> tmp(moving.release());
tmp.swap(*this);
return *this;
}
// Remove compiler generated copy semantics.
UP(UP const&) = delete;
UP& operator=(UP const&) = delete;
// Const correct access owned object
T* operator->() const {return data;}
T& operator*() const {return *data;}
// Access to smart pointer state
T* get() const {return data;}
explicit operator bool() const {return data;}
// Modify object state
T* release() noexcept
{
T* result = nullptr;
std::swap(result, data);
return result;
}
void swap(UP& src) noexcept
{
std::swap(data, src.data);
}
void reset()
{
T* tmp = release();
delete tmp;
}
};
template<typename T>
void swap(UP<T>& lhs, UP<T>& rhs)
{
lhs.swap(rhs);
}
}