为什么 unique

编程入门 行业动态 更新时间:2024-10-28 08:29:03
本文介绍了为什么 unique_ptr 和 shared_ptr 不会使构造它们的指针无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

注意:这是一个API 设计问题,依赖于unique_ptr 和share_ptr 的构造函数的设计code> 是为了提出问题,但不打算对他们当前的规范提出任何更改.

A note: this is an API design question, riding on the design of the constructors of unique_ptr and share_ptr for the sake of the question, but not aiming to propose any change to their current specifications.

虽然通常建议使用 make_unique 和 make_shared,但是 unique_ptr 和 shared_ptr 都可以构造来自原始指针.

Though it would usually be advisable to use make_unique and make_shared, both unique_ptr and shared_ptr can be constructed from a raw pointer.

两者都按值获取指针并复制它.两者都允许(即:不阻止)继续使用在构造函数中传递给它们的原始指针.

Both get the pointer by value and copy it. Both allow (i.e. in the sense of: do not prevent) a continuance usage of the original pointer passed to them in the constructor.

下面的代码编译并得到double free的结果:

The following code compiles and results with 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 和shared_ptr 的相关构造函数希望将原始指针作为rvalue 获取,则它们都可以防止上述情况,例如对于 unique_ptr:

Both unique_ptr and shared_ptr could prevent the above if their relevant constructors would expect to get the raw pointer as an rvalue, e.g. for unique_ptr:

template<typename T> class unique_ptr { T* ptr; public: unique_ptr(T*&& p) : ptr{p} { p = nullptr; // invalidate the original pointer passed } // ...

因此,原始代码不会编译为 lvalue 不能绑定到 rvalue,但使用 std::move 代码编译,同时更详细、更安全:

Thus, the original code would not compile as an lvalue cannot bind to an rvalue, but using std::move the code compiles, while being more verbose and more secured:

int* ptr = new int(9); std::unique_ptr<int> p { std::move(ptr) }; if (!ptr) { // we are here, since ptr was invalidated }

很明显,用户可以使用智能指针解决许多其他错误.常用的说法是你应该知道如何正确使用语言提供的工具,而C++不是为了监视你等

It is clear that there can be dozens of other bugs a user can do with smart pointers. The commonly used argument of you should know how to properly use the tools provided by the language, and C++ is not designed to watch over you etc.

但是,似乎可以有一个选项来防止这个简单的错误并鼓励使用 make_shared 和 make_unique.甚至在 C++14 中添加 make_unique 之前,仍然总是可以选择不带指针变量的直接分配,如:

But still, it seems that there could have been an option for preventing this simple bug and to encourage usage of make_shared and make_unique. And even before make_unique was added in C++14, there is still always the option of direct allocation without a pointer variable, as:

auto ptr = std::unique_ptr<int>(new int(7));

似乎请求右值引用到一个指针作为构造函数参数可以增加一点额外的安全性.此外,当我们获得传递的指针的所有权时,获取 rvalue 的语义似乎更准确.

It seems that requesting rvalue reference to a pointer as the constructor parameter could add a bit of an extra safety. Moreover, the semantics of getting rvalue seems to be more accurate as we take ownership of the pointer that is passed.

关于为什么标准不采用这种更安全的方法的问题?

一个可能的原因可能是上面建议的方法会阻止从 const 指针 创建 unique_ptr,即以下代码将无法使用建议的方法编译:

A possible reason might be that the approach suggested above would prevent creating a unique_ptr from const pointers, i.e. the following code would fail to compile with the proposed approach:

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

但我相信,这似乎是一个值得忽视的罕见场景.

But this seems to be a rare scenario worth neglecting, I believe.

或者,如果需要支持从 const 指针初始化是反对所提出方法的有力论据,那么仍然可以通过以下方式实现更小的步骤:

Alternatively, in case the need to support initialization from a const pointer is a strong argument against the proposed approach, then a smaller step could still be achieved with:

unique_ptr(T* const&& p) : ptr{p} { // ...without invalidating p, but still better semantics? }

推荐答案

我认为答案很简单:零开销.unique_ptr 不需要此更改即可正常工作,因此标准不需要它.如果您认为这提高了足够的安全性值得,您可以要求您的实现添加它(可能在一个特殊的编译标志下).

I think the answer is simple: zero overhead. This change isn't needed for unique_ptr to be functional, so the standard doesn't require it. If you think this improves safety enough to worth it, you can ask your implementation to add it (maybe under a special compilation flag).

顺便说一句,我希望静态分析器有足够的知识来警告这种代码模式.

BTW, I'd expect static analyzers to know enough to warn against this code pattern.

更多推荐

为什么 unique

本文发布于:2023-07-29 08:19:34,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1239015.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:unique

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!