Skip to main content
Tweeted twitter.com/StackCodeReview/status/1373514723791138817
added 27 characters in body
Source Link
Matias Cicero
  • 547
  • 2
  • 4
  • 10

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:

  1. Is it well-formed? i.e. does it follow common C++ standard and patterns (for example, should private members be declared before public ones?
  2. Am I missing something regarding functionality? Is there maybe a bug in my code that I'm not seeing?

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).

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:

  1. Is it well-formed? i.e. does it follow common C++ standard and patterns (for example, should private members be declared before public ones?
  2. Am I missing something regarding functionality? Is there maybe a bug in my code that I'm not seeing?

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).

For 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:

  1. Is it well-formed? i.e. does it follow common C++ standard and patterns (for example, should private members be declared before public ones?
  2. Am I missing something regarding functionality? Is there maybe a bug in my code that I'm not seeing?
edited tags
Link
Source Link
Matias Cicero
  • 547
  • 2
  • 4
  • 10

My implementation for std::unique_ptr

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).

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:

  1. Is it well-formed? i.e. does it follow common C++ standard and patterns (for example, should private members be declared before public ones?
  2. Am I missing something regarding functionality? Is there maybe a bug in my code that I'm not seeing?