【问题标题】:Purpose of shared_ptr<T>&& as constructor argumentshared_ptr<T>&& 作为构造函数参数的目的
【发布时间】:2012-05-14 13:38:47
【问题描述】:

这个问题扩展了之前的post 讨论boost::shared&lt;T&gt;&amp; 作为构造函数参数的有用性:

class SomeClass {  
    SomeClass( const boost::shared_ptr<SomeOtherClass>& );  
} 

用右值引用参数代替boost::shared_ptr&lt;T&gt;&amp; 有什么好处吗?

class SomeClass {  
    SomeClass( const boost::shared_ptr<SomeOtherClass>&& );  
}    

特别是,对于多线程设置,具有 shared_ptr 类型的右值引用的构造函数会比按值传递或按引用传递更有用吗?

【问题讨论】:

  • 如果您采用右值引用,您可以将shared_ptr 移动 到内部成员中,而不是复制它。复制shared_ptr 会导致它增加其引用计数,这比人们最初想象的要昂贵得多。请注意,复制 shared_ptr 是线程安全的,而移动一个则不是。

标签: c++ constructor c++11 shared-ptr rvalue-reference


【解决方案1】:

shared_ptr 并不特别。与几乎任何其他对象相同的规则适用于它。你会做一个 const rvalue 引用参数吗?我看不出任何正当理由。其他类的右值引用呢?除了在类自己的移动构造函数和移动赋值运算符中,在大多数情况下,您不应该通过右值引用获取对象。如果您需要对象的副本,则按值获取它,然后移动它,如下所示:

class SomeClass {
    std::shared_ptr<SomeOtherClass> myptr;
public:
    SomeClass(std::shared_ptr<SomeOtherClass> yourptr)
        :myptr(std::move(yourptr))
    {}
};

如果您不需要副本,那么如果您的意图只是检查它,则通过 const 引用获取它,或者如果您打算修改它,则通过普通引用获取它。

如果你想保证你不会修改指向的对象,那么你可以接受const std::shared_ptr&lt;const SomeOtherClass&gt; &amp;,即使参数没有内部 const 限定符也可以。

【讨论】:

  • 如果你想强调你拥有某物的所有权,我认为右值 ref 参数是完全可以接受的。
  • @Xeo:如果您按值获取参数并移动它,那么您正在拥有它。
【解决方案2】:

const 右值没有任何意义。但是通过右值获取可以更快地转移所有权,因为只需要交换。

【讨论】:

    【解决方案3】:

    我不确定是否存在诸如 const 右值引用之类的东西,我也不知道它是什么意思。当它到达函数并有了名称时,它与 const 左值引用基本相同(如果它有名称,则左值就是规则)。不允许您移动它。

    我不确定在呼叫站点上这意味着什么……如果有的话。当然,它只会把人搞糊涂,所以很糟糕。

    坦率地说,如果这样编译,我会有点恼火。不过我不能说这是违法的。

    现在,去掉 const 部分,你就有了不同的故事。现在您可以“移动”shared_ptr。我相当怀疑 shared_ptr 有一个移动构造函数,但也许它确实有。这意味着移动总是意味着:接收实体可以接管提供的变量,可能会破坏它。

    【讨论】:

    • 有 const rvalue 引用这样的东西,但它非常没用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-05
    • 2018-03-03
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多