Sartyro
Sartyro

Reputation: 29

Difference between destructors in my class

I'm implementing a simplified unique pointer. Everything was pretty clear, but I wonder about the destructor in my class.

Should it be ~unique_pointer(){obj->~T();} or ~unique_pointer(){delete obj}?

I really don't see a difference between these. Can you explain how they work?

Below is the whole class:

template<class T>
class unique_pointer{
private:
    T*obj;
public:
    unique_pointer(const T* obj):obj{obj}{}
    ~unique_pointer(){obj->~T();}
    
    T operator*() const { return *obj; }
    T* operator->() const { return obj; }

    T* release(){
        T* temp = obj;
        obj = 0;
        return obj;
    }
};

Upvotes: 1

Views: 77

Answers (1)

eerorika
eerorika

Reputation: 238321

It should be ~unique_pointer(){obj->~T();} or ~unique_pointer(){delete obj}. I really don't see difference between each other.

obj->~T() destroys the pointed object. If the object is stored in dynamic memory, then the memory is not dealloated. If nothing else deallocates the memory, then the memory is leaked. Given that the point of a unique pointer is to manage dynamic allocation, doing this would be rather pointless.

delete obj If obj was created with allocating new, then this destroys the object and frees the deallocation. Otherwise the behaviour of the program is undefined. This is what std::default_delete, the default deleter of std::unique_ptr, does (unless the template type argument is T[] in which case it calls delete[] instead).

Some simple rules of thumb that apply to most cases:

  • If you new, then delete
  • Delete only if you newed
  • Never delete more than once
  • If you newed an array, then delete[] instead
  • Don't use new nor delete except in implementation of a smart pointer or similar low level memory management class
  • If you malloc, then free
  • Never free more than once
  • Don't malloc
  • If you placement new, then call destructor explicitly
  • Don't placement new unless you know what you're doing

P.S. Your release doesn't seem to make sense, as it doesn't release obj, has an unused variable temp, and uses some undeclared val.

Furthermore, it is copyable and have undefined behaviour if copied or moved. A unique pointer shouldn't be copyable, and needs a custom definition for move.

Upvotes: 7

Related Questions