标准库的源码有一千来行,我就写个80几行的缩水版好了
//默认删除器
template <typename Tp> struct default_delete{
constexpr default_delete( void ) noexcept = default;
//支持隐式转换
template <typename Up> requires std::convertible_to<Up *, Tp *>
//通用转发构造
default_delete(const default_delete<Up>& ) noexcept {}
//类型萃取,函数体内不做任何事情
void operator()(Tp *ptr) const{
//类型完整性静态断言检查
static_assert(!std::is_void<Tp>::value || sizeof(Tp)>0 );
delete ptr;
}
};
//数组特化
template <typename Tp> struct default_delete<Tp[]>{
constexpr default_delete(void) noexcept = default;
template <typename Up> requires std::convertible_to<Up(*)[], Tp(*)[]>
default_delete(const default_delete<Up[]>&) noexcept {}
template<typename Up>
typename std::enable_if<std::is_convertible<Up(*)[], Tp(*)[]>::value>::type
operator()(Up* ptr) const{
static_assert(sizeof(Tp)>0);
delete [] ptr;
}
};
template <typename Tp, typename Dp = default_delete<Tp>>
class unique_ptr{
private: Tp *ptr{nullptr};
//全特化友元声明
template <typename UTp, typename UDp>
friend class unique_ptr;
public:
constexpr unique_ptr(void) noexcept = default;
unique_ptr(Tp *p) : ptr(p) {}
//nullptr的支持
unique_ptr(std::nullptr_t) {}
~unique_ptr(void){
if(ptr) Dp{}(ptr);
}
//弃置拷贝
unique_ptr(unique_ptr const &) = delete;
unique_ptr& operator=(unique_ptr const&) = delete;
//隐式转换的移动语义
template <typename UTp, typename UDp>
requires std::convertible_to<Tp *, UTp *> && std::same_as<Dp, UDp>
unique_ptr(unique_ptr<UTp, UDp>&& other)
{ ptr = std::exchange(other.ptr, nullptr); }
unique_ptr& operator=(unique_ptr&& other){
if(this != &other) {
if(ptr) {
Dp{}(ptr);
ptr = std::exchange(other.ptr, nullptr);
}
}
return *this;
}
Tp *get(void) const{
return ptr;
}
Tp *release(void) {
return std::exchange(ptr, nullptr);
}
void reset(Tp* p = nullptr) {
if(ptr) Dp{}(ptr);
ptr = p;
}
Tp *operator->() const{
return ptr;
}
Tp& operator*() const{
return *ptr;
}
};
//数组重载
template <typename Tp, typename Dp>
//主模板递归继承 基类取得模式
class unique_ptr<Tp[], Dp>: unique_ptr<Tp, Dp>{};
template <typename Tp, typename... Args>
//延时接口
unique_ptr<Tp> make_unique(Args&&... args){
return unique_ptr<Tp>(new Tp(std::forward<Args>(args)...));
}
//重载版本
template <typename Tp>
unique_ptr<Tp> make_unique(void){
return unique_ptr<Tp>(new Tp);
}