我应该从使用boost::shared_ptr转换到std::shared_ptr吗?

73
我想在GCC中启用对C++0x的支持,使用-std=c++0x。我不一定需要GCC 4.5(和即将到来的4.6)中已支持的C++11特性中的任何一个,但我想开始逐渐习惯它们。例如,在我使用迭代器的几个地方,auto类型会很有用。
但再次强调,我不需要目前支持的任何特性。这里的目标是鼓励我将新标准的特性融入我的编程“词汇”中。
从您了解的C++11支持情况来看,在GCC中启用它,并通过例如从使用boost::shared_ptr切换到std::shared_ptr来拥抱它,这是一个好主意吗?因为两者不能混合使用。
PS:我知道这个好问题比较了不同风格的shared_ptr,但我要求更高层次的建议,即在标准最终确定之前使用哪种。另一种表达方式是,当像GCC这样的编译器表示支持“实验性特性”时,这是否意味着我可能会在编译过程中遇到奇怪的错误,这些错误将成为主要时间消耗和StackOverflow上加密问题的源泉?

编辑:我决定从std::shared_ptr切换回来,因为我不相信它在GCC 4.5中的支持,正如在这个问题的示例中所示


7
我在想,如果使用支持的编译器,boost是否可以仅使用typedef到std::shared_ptr? - Mark Ransom
在这里找不到具体的问题?投票关闭。 - user7116
4
我认为问题很明确,只是答案不是简单的“是”或“否”。回答需要一个正反双方的列表,就像我标记为答案的那个一样。问题实质上是:你建议在标准最终确定之前使用std::shared_ptr吗?为什么还是为什么不? - Alan Turing
8个回答

62

使用std::shared_ptr的几个原因:

  • 您可以删除对Boost的依赖。
  • 调试器。根据编译器和调试器的不同,调试器可能对std::shared_ptr进行“智能”处理并直接显示所指向的对象,而对于boost的实现则不会这样做。至少在Visual Studio中,std::shared_ptr在调试器中看起来像一个普通指针,而boost::shared_ptr则暴露了一堆boost的内部细节。
  • 其他在链接问题中定义的新功能。
  • 您将获得一个几乎保证启用了移动语义的实现,这可能会节省一些引用计数修改。(理论上-我自己没有测试过)至少截至2014-07-22,boost::shared_ptr理解移动语义。
  • std::shared_ptr正确地在数组类型上使用delete [],而boost::shared_ptr在这种情况下会导致未定义的行为(您必须使用shared_array或自定义删除器)(实际上,我改变了立场。请参见此处——特化为unique_ptr而不是shared_ptr。)

还有一个重要的原因不是这样做:

  • 您将限制自己只能使用C++11编译器和标准库实现。

最后,您实际上不必做出选择。(如果您针对特定的编译器系列(例如MSVC和GCC),则可以轻松地扩展此内容以在可用时使用std::tr1::shared_ptr。不幸的是,似乎没有标准的方法来检测TR1支持)

#if __cplusplus > 199711L
#include <memory>
namespace MyProject
{
    using std::shared_ptr;
}
#else
#include <boost/shared_ptr.hpp>
namespace MyProject
{
    using boost::shared_ptr;
}
#endif

5
typedef shared_ptr std::shared_ptr 的意思是“将 shared_ptr 定义为 std::shared_ptr”。 - GManNickG
1
@GManNickG:lol。发现得好。该死的typedef反过来了!(感觉像一个赋值给我) - Billy ONeal
@GManNickG:嗯...回头看看,也许using语句会更好。你觉得呢? - Billy ONeal
是的,模板using是正确的:template <typename T> using shared_ptr = std::shared_ptr<T>;。问题在于这是C++11的特性,所以你不能在boost::shared_ptr中使用它。 :) C++03的方法是另一种具有内部typedef的类型 - GManNickG
@GManNickG:更好了吗?(抱歉,我没有安装boost来确保这个能正常工作) - Billy ONeal
显示剩余3条评论

14

我认为这取决于你使用boost的程度。我个人只非常少量地使用它(事实上,仅在一个项目中使用随机数库)。最近,我开始在我的其他项目中使用-std=c++0x,并在其中使用新的std::库功能,例如shared_ptr。我喜欢我的项目具有最小的依赖性,因此我宁愿依赖于编译器的标准库实现而不是boost。

但我认为没有一个适用于所有情况的答案。


13

如果有可能的话,应该始终使用 std::shared_ptr 而不是 boost。这是因为所有使用 shared_ptr 的新接口都将使用标准共享指针。


7

也许开始养成使用std::shared_ptr的习惯并让编译器允许是个不错的主意。因为接口与boost的shared_ptr相同,所以如果需要,您总是可以切换回去。


4

如果您只在一个平台上进行构建,那么没问题(切换平台即可)
(注意:您有单元测试来验证向后兼容性吗?)

如果您在多个平台上编译,则需要进行更多的验证,以确保您使用的所有平台都支持g++ 4.5上的功能(例如,在为MAC/Linux构建时,默认的Mac g++编译器仍然落后于Linux上的默认编译器)。


4
我发现std::shared_ptr比boost::shared_ptr更快。我进行了一个测试,您可以查看代码并查看比较boost、Qt和std共享指针的饼图结果。 enter image description here https://www.osletek.com...

1
我很惊讶地发现,使用malloc和new的情况要快得多。如果性能损失是10倍的话,我认为没有人会想使用智能指针。你的测试用例不可比较:
  1. malloc和new只被调用一次,分配一个大小为LENGTH的数组,而在所有其他情况下,分配是做了LENGTH次的。
  2. 对于malloc和new,你将rand的结果赋值给了分配的数组,而在所有其他情况下,分配的结果被推回到一个向量中,导致进一步的内存分配/重新分配。
- andreas buykx
3
顺带一提,饼图不是展示这种数据的非常有用的方式。 这篇文章会告诉你为什么... https://www.perceptualedge.com/articles/visual_business_intelligence/save_the_pies_for_dessert.pdf - andreas buykx

4

除了实现一致性之外,boost::shared_ptr 目前仍保留着至少两个优于 std::shared_ptr 的利基优势:


4
切换到 std::shared_ptr 的另一个原因是:它支持 std::unique_ptr,即有构造函数。

boost::shared_ptr 不支持。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接