为什么std::unique_ptr的get()得到的原始指针不能删除对象,它是如何实现的

why the raw pointer get by std::unique_ptr's get() can not delete the object and how is that implemented

如以下代码所示,我试图通过从 unique_ptr 获取的原始指针删除对象。但是,正如输出所示,编译器报告了错误。但是,对于原始指针,我们可以这样做 int *p1 = new int{100}; int* p2 = p1; delete p2;.

此外,我认为 unique_ptr 通过移动语义维护其所有权。作为unique_ptrreturns原始指针的get()函数,unique_ptr如何还能拥有对象的所有权。同时,为什么原始指针没有获得所有权。同时,我很困惑这是如何实现的。谢谢

#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;
}

代码在MacOs上执行,输出为:

std::unique_ptr 是一个非常简单的 class。从概念上讲,基本上就是这样:

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
};

它只有一个指针成员,delete在它的析构函数中是pointed-to对象。实际上还有更多,但基本上就是这样。

get 成员只是 returns unique_ptr 的托管指针的副本。而已。由于 unique_ptr 的指针成员仍指向该对象,其析构函数仍将 delete 该对象。如果您还通过另一个指向该对象的指针 delete 该对象,那么它将获得 deleted 两次,这会导致未定义的行为。

另一方面,

release 成员函数在返回其原始值的副本之前将 unique_ptr 的指针成员设置为 nullptr。由于其成员指针为空,其析构函数不会删除任何内容。