我正在学习智能指针(std::auto_ptr
),只读here和here智能指针(std::auto_ptr
)不应放在容器中(即{{ 1}})因为即使大多数编译器也不会抱怨并且它看起来似乎是正确的。没有规则说智能指针不会在内部复制(例如std::vector
类)并传输其所有权,然后指针将变为NULL。最后,一切都会搞砸。
实际上,这种情况多久发生一次?
有时我会有指针的向量,如果将来我决定我想要一个智能指针的矢量,我的选择是什么?
我知道C ++ 0x和Boost库,但就目前而言,我更倾向于采用STL方法。
答案 0 :(得分:16)
是的,您确实无法将std::auto_ptr
与标准容器一起使用。 std::auto_ptr
副本不等同,并且因为允许标准容器(和算法)随意复制它们的元素,这会搞砸。也就是说,复制std::auto_ptr
的操作具有其他的含义而不仅仅是对象的副本:它意味着转移所有权。
您的选择是:
答案 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容器中使用该类。