As the following code presents, I tried to delete the object by the raw pointer get from a unique_ptr. But, as the output shows, the complier reported errors. However, for raw pointers, we can do this int *p1 = new int{100}; int* p2 = p1; delete p2;
.
Besides, I thought that unique_ptr maintain its ownership by move semantics. As the get() function of unique_ptr returns the raw pointer, how does the unique_ptr can still have the ownership of the object. Meanwhile, why the raw pointer doesn't get the ownership. At the same time, I am confusing how does this implemented. Thanks.
#include <iostream>
#include <memory>
int main(int argc, char const *argv[])
{
std::unique_ptr<int> newPtr = std::make_unique<int>(1234);
std::cout << *newPtr << std::endl;
int* rawInt = newPtr.get();
*rawInt = 200;
delete rawInt;
rawInt = nullptr;
std::cout << *newPtr << std::endl;
return 0;
}
The code was performed on MacOs and the output is:
CodePudding user response:
std::unique_ptr
is a really simple class. Conceptually, it's basically just this:
template <typename T>
class unique_ptr
{
private:
T* ptr;
public:
unique_ptr(T* p) ptr{p} {}
~unique_ptr() { delete ptr; }
T* get() { return ptr; }
T* release() {
T* p = ptr;
ptr = nullptr;
return p;
}
// other stuff
};
It just has a pointer member, and delete
s the pointed-to object in its destructor. In reality there's a bit more to it, but that's essentially it.
The get
member just returns a copy of the unique_ptr
's managed pointer. That's it. Since the unique_ptr
's pointer member is still pointing to that object, its destructor will still delete
the object. If you also delete
that object via another pointer to it then it will get delete
d twice, which results in undefined behavior.
The release
member function, on the other hand, sets the unique_ptr
's pointer member to nullptr
before returning a copy of its original value. Since its member pointer is null, its destructor won't delete anything.