注意:这是一个API设计问题,出于这个问题,它基于unique_ptr
和share_ptr
的构造函数的设计,但并不旨在建议对他们当前的规格。
尽管通常建议使用make_unique
和make_shared
,但是unique_ptr
和shared_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;
如果[rvalue
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的构造函数的设计,但并不旨在建议对其当前版本进行任何更改...