为什么 std::unique_ptr 构造函数接受外部指针?

FRR*_*FRR 4 c++

我对 cpp 比较陌生,正在学习智能点。我想知道以下几点:

为什么要构造std::unique_ptr一个lvalue允许的?

只允许构造std::unique_ptr带有右值的 an 来避免邪恶的事情不是更安全吗?

std::unique_ptr<int> createInt() {
    int* a = new int(99);
    std::unique_ptr<int> foo(a);
    delete a;
    return foo;
}
Run Code Online (Sandbox Code Playgroud)

我意识到你必须疯了才能写出这样的东西,但我很高兴让编译器为此对你大喊大叫。所以我想知道,为什么 unique_ptr 的左值初始化是一件事?

编辑:用户@aler egal 更优雅地表达了我的想法:

“原则上,你可以有一个构造函数unique_ptr<int>(int*&& ptr)即假设PTR的所有权,然后将其设置为null。这将阻止释放后使用,在这个具体的例子(因为你被迫std::move(a)因为调用删除一个空指针有没有效果)但这将是一个非常奇怪的反模式。”

kes*_*Him 6

这是悬空指针的经典示例!与智能指针看起来不同,它们只是普通(原始)指针的包装器,可以自行管理内存并为您提供一些附加功能。

考虑以下示例:

int* someFunc() {
    int* ptr;
    int* ptr2 = ptr;
    delete ptr;
    return ptr2;
}
Run Code Online (Sandbox Code Playgroud)

这就是你本质上在做的。
它们已经被制作成可以在任何时候代替原始拥有指针使用;意思是,它们也可以悬挂!因此,如果不允许左值初始化,那是您不能使用智能指针的一个用例,尽管我同意,这是您也不能使用的一种情况!

上面带有智能指针的代码正是您所尝试的。

现在,C++ 将逻辑留给您……完全。如果您想用脚射击自己,请继续,C++ 不会吠叫。C++ 不检查内存使用情况和缓冲区溢出以及对已删除内存的访问。简单地说,这是 C++ 程序员的工作,如果他/她想用脚开枪,他/她可以自由地这样做!


此外,通常建议使用std::make_ptr()ctor,因为前者启用了异常