19

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

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

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

我知道 C++0x 和 Boost 库,但现在,我更愿意坚持使用 STL 方法。

4

5 回答 5

16

是的,你真的不能使用std::auto_ptr标准容器。std::auto_ptr副本不等效,并且因为允许标准容器(和算法)随意复制它们的元素,所以这搞砸了。也就是说,复制 a 的操作不仅仅具有对象的复制std::auto_ptr含义:它意味着转移所有权

您的选择是:

  1. 使用Boost 智能指针库。这可以说是您最好的选择。
  2. 使用原始指针。只要您正确管理指针,这是快速且安全的。有时这可能很复杂或困难。例如,您必须自己处理(避免)双重删除问题。
  3. 使用您自己的引用计数智能指针。那太傻了;使用 Boost 智能指针。
于 2011-01-02T09:42:25.190 回答
11

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

于 2011-01-02T09:38:10.677 回答
3

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

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

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

于 2011-01-02T09:38:38.500 回答
2

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

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

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

于 2011-01-02T10:07:17.620 回答
1

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

于 2014-08-30T13:02:59.907 回答