2
\$\begingroup\$

I know I haven't implemented many methods, and haven't specialized it for T[], but I just want to see if what I coded is good or bad.

template< class T >
class unique_ptr
{
private:
 T* ptr;
 
public:
 unique_ptr() noexcept : ptr(nullptr) {}
 ~unique_ptr() noexcept { release(); }
 explicit unique_ptr(T* data) noexcept;
 unique_ptr(const unique_ptr& rhs) = delete;
 unique_ptr& operator=(const unique_ptr& rhs) = delete;
 unique_ptr(unique_ptr&& rhs) noexcept;
 unique_ptr& operator=(unique_ptr&& rhs) noexcept
 {
 ptr = std::move(rhs.ptr);
 }
 T& operator*() { return *get(); }
 T* get() const noexcept;
 T* release() noexcept;
};
template< class T >
unique_ptr<T>::unique_ptr(T* data) noexcept : ptr(data) {}
template< class T >
unique_ptr<T>::unique_ptr(unique_ptr&& rhs) noexcept
{
 ptr = std::move(rhs.ptr);
}
template< class T >
T* unique_ptr<T>::get() const noexcept
{
 return ptr;
}
template < class T >
T* unique_ptr<T>::release() noexcept
{
 auto old_ptr = ptr;
 ptr = nullptr;
 return old_ptr;
}
template< typename T, typename ...Args >
unique_ptr<T> make_unique(Args&&... args)
{
 return unique_ptr<T>(new T(std::forward<Args>(args)...));
}
Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges201 bronze badges
asked Aug 9, 2023 at 18:08
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

What's implemented so far looks mostly fine, except for the destructor. I would add operator->() as soon as possible, since we have operator*() - they come as a pair, and I don't think it's yet defaultable in the way that != can be synthesized when we provide ==.

Technically, we don't need = delete declarations of copy-construct/assign, since providing move-construct/assign inhibits those. But I like showing that explicitly - it can help the reader.

We could make the T* constructor also be the default constructor, by using a default argument:

 explicit unique_ptr(T* data = nullptr) noexcept;

operator* needs to be const (it can be noexcept, too).

release() can be simplified to just return std::exchange(ptr, nullptr);. It probably should make marked [[nodiscard]] since it transfers ownership of the pointer.

There's a bug in the destructor: we just call release(), abandoning the ownership of the pointer. But we actually need to free the owned object instead:

 ~unique_ptr() noexcept { delete ptr; }

(Remember that delete on a null pointer is safe, and does nothing).

answered Aug 11, 2023 at 9:22
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.