容器中的智能指针如std :: vector?

时间:2011-01-02 09:29:42

标签: c++ pointers std smart-pointers auto-ptr

我正在学习智能指针(std::auto_ptr),只读herehere智能指针(std::auto_ptr)不应放在容器中(即{{ 1}})因为即使大多数编译器也不会抱怨并且它看起来似乎是正确的。没有规则说智能指针不会在内部复制(例如std::vector类)并传输其所有权,然后指针将变为NULL。最后,一切都会搞砸。

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

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

我知道C ++ 0x和Boost库,但就目前而言,我更倾向于采用STL方法。

5 个答案:

答案 0 :(得分:16)

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

您的选择是:

  1. 使用Boost Smart Pointers library。这可以说是你最好的选择。
  2. 使用原始指针。只要你正确地管理指针,这是快速和安全的。有时这可能很复杂或困难。例如,您必须自己处理(避免)双重删除问题。
  3. 使用您自己的引用计数智能指针。那太傻了;使用Boost Smart Pointer。

答案 1 :(得分:9)

您所指的问题与auto_ptr有关,因为它会移动副本的所有权。 shared_ptr和unique_ptr可以很好地处理容器。

答案 2 :(得分:3)

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

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

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

答案 3 :(得分:2)

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

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

所以,结论:这只是一个坏主意,除了头痛之外什么也没带来

答案 4 :(得分:1)

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