为什么unique_ptr和shared_ptr不会使它们的构造指针无效?

问题描述 投票:1回答:1

注意:这是一个API设计问题,出于这个问题,它基于unique_ptrshare_ptr的构造函数的设计,但并不旨在建议对他们当前的规格。


尽管通常建议使用make_uniquemake_shared,但是unique_ptrshared_ptr都可以由原始指针构造。

都按值获取指针并进行复制。两者都允许(即:[[no not prevent的意义)连续使用构造函数中传递给它们的原始指针。

下面的代码使用double free进行编译和结果:

int* ptr = new int(9); std::unique_ptr<int> p { ptr }; // we forgot that ptr is already being managed delete ptr; 如果[unique_ptr的相关构造函数希望将原始指针作为

rvalue

来获取,例如,对于unique_ptr:

shared_ptr因此,原始代码无法编译为

lvalue
无法绑定到

rvalue,但是使用template<typename T> class unique_ptr { T* ptr; public: unique_ptr(T*&& p) : ptr{p} { p = nullptr; // invalidate the original pointer passed } // ... 可以编译代码,同时使代码更冗长和更安全:

std::move显然,用户可以使用智能指针来处理许多其他错误。
您应该知道如何正确使用该语言提供的工具

C ++并非为监视您而设计]]等的常用参数。但是,似乎仍然可以选择防止这个简单的错误并鼓励使用int* ptr = new int(9); std::unique_ptr<int> p { std::move(ptr) }; if (!ptr) { // we are here, since ptr was invalidated } make_shared。甚至在C ++ 14中添加make_unique之前,仍然总是可以选择不使用指针变量的直接分配,例如:make_unique

看来,向指针请求

rvalue reference作为构造函数参数可能会增加一点安全性。此外,随着我​​们对传递的指针的所有权,获取

rvalue

的语义似乎更加准确。
关于为什么标准不采用这种更安全的方法?

[可能的原因可能是上述建议的方法将阻止从


const指针

创建auto ptr = std::unique_ptr<int>(new int(7)); ,即以下代码将无法使用建议的方法进行编译:
unique_ptr但是我相信这似乎是一个值得忽略的罕见情况。
或者,如果需要从const指针支持初始化是强烈反对所提出的方法的论点,那么仍然可以通过以下步骤来实现较小的步骤:

int* const ptr = new int(9); auto p = std::unique_ptr { std::move(ptr) }; // cannot bind `const rvalue` to `rvalue`

注:这是一个API设计问题,出于该问题的考虑,它依赖于unique_ptr和share_ptr的构造函数的设计,但并不旨在建议对其当前版本进行任何更改...

c++ shared-ptr api-design unique-ptr rvalue-reference
1个回答
3
投票
© www.soinside.com 2019 - 2024. All rights reserved.