I just finished learning about move semantics and realized that a nice practical example for this concept is unique_ptr (it cannot be copied, only moved).
AsFor learning purposes, and as a personal experiment, I proceed to try to create my implementation for a smart unique pointer:
template<typename T>
class unique_ptr {
private:
T* _ptr;
public:
unique_ptr(T& t) {
_ptr = &t;
}
unique_ptr(unique_ptr<T>&& uptr) {
_ptr = std::move(uptr._ptr);
uptr._ptr = nullptr;
}
~unique_ptr() {
delete _ptr;
}
unique_ptr<T>& operator=(unique_ptr<T>&& uptr) {
if (this == uptr) return *this;
_ptr = std::move(uptr._ptr);
uptr._ptr = nullptr;
return *this;
}
unique_ptr(const unique_ptr<T>& uptr) = delete;
unique_ptr<T>& operator=(const unique_ptr<T>& uptr) = delete;
};
For a small set of test cases, this is working like the real unique_ptr.
However, it just seems too simple enough.
I have two questions regarding this code:
- Is it well-formed? i.e. does it follow common C++ standard and patterns (for example, should private members be declared before public ones?
- Am I missing something regarding functionality? Is there maybe a bug in my code that I'm not seeing?