【问题标题】:Why is std::tr1::shared_ptr<>.reset() so expensive?为什么 std::tr1::shared_ptr<>.reset() 这么贵?
【发布时间】:2010-06-15 13:11:15
【问题描述】:

分析一些大量使用 shared_ptrs 的代码,我发现 reset() 非常昂贵。

例如:

struct Test {
    int i;
    Test() {
        this->i = 0;
    }
    Test(int i) {
        this->i = i;
    }
} ;
...
auto t = make_shared<Test>(1);
...
t.reset(somePointerToATestObject);

跟踪最后一行中的 reset()(在 VC++ 2010 下),我发现它创建了一个新的引用计数对象。

有没有更便宜的方法,可以重用现有的引用计数并且不会打扰堆?

【问题讨论】:

  • 只是想知道,你为什么要共享1 的任意指针值?
  • @ian:他不是。你知道make_shared 是做什么的吗?
  • somePointerToATestObject 是什么类型?
  • @fred:我以为我做到了。和qt的qsharedpointer一样吧?
  • 算了。 shared_ptr 重置不是您的瓶颈,也永远不会。

标签: c++ visual-studio-2010 shared-ptr tr1


【解决方案1】:

在一般情况下,您不能重用现有的引用计数,因为可能有其他 shared_ptrs 或 weak_ptrs 在使用它。

如果您可以使用make_shared() 创建somePointerToATestObject,那么实现可以为引用计数和对象使用单个堆分配。这将为您节省一个堆分配。

【讨论】:

  • 不幸的是,reset() 没有将 shared_ptr 作为参数的版本
  • @Paul:对;您只需将其分配为t = otherSharedPtr
  • 我不明白这个答案。 tr1::shared_ptr(与 boost::shared_ptr 不同)没有 reset 重载需要另一个 shared_ptrreset 的每次调用都必须创建一个引用计数以绑定到提供的指针,因为即使提供的指针当前由另一个 @ 拥有,也无法(enable_shared_from_this 不是必需的)获得任何现有的引用计数987654332@。如果提供的指针由另一个智能指针(shared_ptr 或其他)拥有,那么使用reset 和“告诉”shared_ptr 它拥有所有权肯定是程序员错误?
  • @Charles:对。就像我在评论中说的那样,应该简单地使用赋值。我在答案中想说的是,当创建somePointerToATestObject 时,应该立即将其分配给shared_ptr。那么你完全不用担心使用reset()。我不确定我是否理解您不同意的部分:-/。
  • 你的第一句话让我很困惑。如果 somePointerToATestObject 被传递给 reset 那么它只能是一个原始指针,所以我不明白“现有的引用计数”是从哪里来的。原始指针(不一定)与现有的引用计数相关联。如果原始指针实际上来自另一个shared_ptr,那么这是一个彻头彻尾的程序员错误。 reset 不可能或应该使用它的引用计数。这将违反接口。
猜你喜欢
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
  • 2017-08-15
相关资源
最近更新 更多