像 std::vector 这样的容器中的智能指针?

发布于 2024-10-09 16:17:04 字数 504 浏览 0 评论 0原文

我正在学习智能指针 (std::auto_ptr),只需阅读此处此处 智能指针 (std::auto_ptr)不应放入容器(即std::vector)中,因为即使大多数编译器也不会抱怨,而且它可能看起来是正确的。没有规则说智能指针不会在内部复制(例如通过向量类)并转移其所有权,然后指针将变为 NULL。最终,一切都会搞砸。

事实上,这种情况多久发生一次?

有时我有指针向量,如果将来我决定想要有一个智能指针向量,我的选择是什么?

我了解 C++0x 和 Boost 库,但目前,我更愿意坚持使用 STL 方法。

I am learning about smart pointers (std::auto_ptr) and just read here and here that smart pointers (std::auto_ptr) should not be put in containers (i.e. std::vector) because even most compilers won't complain and it might seem correct. There is no rule that says smart pointers won't be copied internally (by vector class for example) and transfer its ownership, then the pointer will become NULL. In the end, everything will be screwed up.

In reality, how often does this happen?

Sometimes I have vectors of pointers and if in the future I decide I want to have a vector of smart pointers what would my options?

I am aware of C++0x and Boost libraries, but for now, I would prefer to stick to a STL approach.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我是有多爱你 2024-10-16 16:17:04

是的,您确实不能将std::auto_ptr与标准容器一起使用。 std::auto_ptr 副本并不等效,并且因为允许标准容器(和算法)随意复制其元素,所以这会把事情搞砸。也就是说,复制 std::auto_ptr 的操作具有不同于单纯对象复制的含义:它意味着转移所有权

您的选择是:

  1. 使用 Boost 智能指针库。这可以说是您的最佳选择。
  2. 使用原始指针。只要您正确管理指针,这既快速又安全。有时这可能很复杂或困难。例如,您必须自己处理(避免)双重删除问题。
  3. 使用您自己的引用计数智能指针。那是愚蠢的;使用升压智能指针。

Yes, you really can't use std::auto_ptr with standard containers. std::auto_ptr copies aren't equivalent, and because standard containers (and algorithms) are allowed to copy their elements at will this screws things up. That is, the operation of copying a std::auto_ptr has a meaning other than a mere copy of an object: it means transferring an ownership.

Your options are:

  1. Use the Boost Smart Pointers library. This is arguably your best option.
  2. Use primitive pointers. This is fast and safe, so long as you manage the pointers properly. At times this can be complex or difficult. For example, you'll have to cope with (avoid) double-delete issues on your own.
  3. Use your own reference-counting smart pointer. That'd be silly; use a Boost Smart Pointer.
独留℉清风醉 2024-10-16 16:17:04

您所指的问题涉及 auto_ptr,因为它会移动副本的所有权。 shared_ptr 和 unique_ptr 与容器一起工作得很好。

The problem you are referring to concerns auto_ptr since it moves ownership on copy. shared_ptr and unique_ptr work just fine with containers.

羁绊已千年 2024-10-16 16:17:04

与标准容器模板一起使用的任何类型都必须符合该容器的要求。特别是,该类型必须满足CopyConstructibleAssignable类型的要求。

许多智能指针确实满足这些要求,并且可以与标准容器一起使用,但 std::auto_ptr 不是其中之一,因为 std::auto_ptr 的副本并不等同于它们被创建或分配的来源。

尽管标准容器的某些实现在某些情况下可以与 auto_ptr 一起使用,但依赖此类实现细节是危险的。

Any type that you use with a standard container template must conform with the requirements for that container. In particular, the type must satisfy the requirements for CopyConstructible and Assignable types.

Many smart pointers do satisfy these requirements and may be used with standard containers but std::auto_ptr is not one of them because copies of std::auto_ptr are not equivalent to the source that they were created or assigned from.

Although some implementations of standard container may work with auto_ptr in some situations it is dangerous to rely on such implementation details.

日久见人心 2024-10-16 16:17:04

理论上,如果您完全了解 STL 容器的内部实现,并且不做任何可能失去 auto_ptr 所有权的事情,则可以将 std::auto_ptr 与 STL 容器一起使用,但实际上,使用带有原始 ptr 的容器要安全得多。

“实际上,这种情况多久发生一次?” - 本身就是一个非常危险的问题。首先,STL——它不是一个单一的标准实现,有很多。每个容器都可以以不同的方式实现容器,因此,为避免所有“容器中的 auto_ptr”地雷而进行高度调整的代码可能会突然切换到另一种 STL 实现。此外,您的代码维护将非常复杂,对代码的任何看起来正确的更改都可能会破坏您的程序。你如何记住这一点或强迫其他维护者记住这一点?在任何可能发生此类更改的地方放置警告?不可能。

所以,结论:这只是一个坏主意,只会带来头痛

theoretically you can use std::auto_ptr with STL containers if you completely understand their internal implementation and don't do anything that can lose auto_ptr ownership, but practically it's much more safe to use containers with raw ptrs.

"In reality, how often does this happen?" - is very dangerous question by itself. first of all, STL - it's not a single standard implementation, there're many. Each one can implement containers in different ways, so your highly tuned code to avoid all "auto_ptr in containers" mines can burst switching to another STL implementation. Also, your code maintenance will be highly complicated, any correctly looking change to your code can break your program. how can you remember that or force others maintainers to remember? putting warnings in any place where such changes can occur? impossible.

so, conclusion: it's just a bad idea that brings nothing but headache

戴着白色围巾的女孩 2024-10-16 16:17:04

对于具有 auto ptr 数据成员的类,我总是有一个返回新 auto ptr 的克隆方法。然后,我实现一个赋值方法和调用克隆方法的复制构造函数(而不是 auto ptr 的默认赋值运算符)。这样您就可以安全地在 STL 容器中使用该类。

For classes that have an auto ptr data member, I always have a clone method that returns a new auto ptr. I then implement an assignment method and copy constructor that call the clone method (and never the default assignment operator of auto ptr). This way you can safely use the class in STL containers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文