如何将智能指针传递给函数?

时间:2012-09-20 19:45:10

标签: c++ c++11 parameter-passing smart-pointers unique-ptr

将对象传递给函数时,相同的规则是否适用于智能指针以及包含动态内存的其他对象?

当我将std::vector<std::string>传递给函数时,我总是考虑以下选项:

  1. 我要更改矢量对象的状态,但是希望在函数完成后反映这些更改,AKA会复制。

    void function(std::vector<std::string> vec);
    
  2. 我要更改矢量对象的状态,并且执行希望在函数完成后反映这些更改,AKA进行引用。

    void function(std::vector<std::string> & vec);
    
  3. 这个对象非常大,所以我最好传递一个引用,但是告诉编译器不要让我改变它。

    void function(std::vector<std::string> const& vec);  
    
  4. 现在这与智能指针的逻辑相同吗?什么时候应该考虑移动语义?关于如何通过智能指针的一些指导是我最想要的。

3 个答案:

答案 0 :(得分:19)

智能指针具有指针语义,而不是值语义(嗯,不是你的意思)。将shared_ptr<T>视为T*;这样对待(好吧,除了参考计数和自动删除)。复制智能指针不会复制它指向的对象,就像复制T*不会复制它指向的T一样。

您根本无法复制unique_ptr。该类的重点是不能被复制;如果它可以,那么它将不是指向对象的唯一(即:单数)指针。您必须通过某种形式的引用或移动来传递它。

智能指针完全是关于他们所指向的所有权。谁拥有这个记忆,谁将负责删除它。 unique_ptr表示唯一所有权:正好一段代码拥有此内存。您可以转移所有权(通过move),但这样做会导致失去内存的所有权。 shared_ptr代表共享所有权。

在所有情况下,在参数列表中使用智能指针代表转移所有权。因此,如果函数采用智能指针,那么它将声明该对象的所有权。如果一个函数不应该取得所有权,那么它根本不应该采用智能指针;使用引用(T&)或者如果你需要可空性,那么指针却永远不会存储它。

如果您传递某人unique_ptr,则给予他们所有权。这意味着,根据独特所有权的性质,您失去内存的所有权。因此,几乎没有理由通过除{value}之外的任何东西传递unique_ptr

同样,如果您想共享某个对象的所有权,则传入shared_ptr。无论您是通过引用还是按价值来做,都取决于您。既然你正在分享所有权,那么无论如何它都会制作一份副本(大概),所以你不妨按价值来看待它。该函数可以使用std::move将其移动到类成员等中。

答案 1 :(得分:4)

智能指针是一个对象,它引用另一个对象来管理它的生命周期。

传递智能指针需要尊重智能助手支持的语义:

  • 传递为const smartptr<T>&始终有效(并且您无法更改指针,但可以更改其指向的状态)。
  • 传递为smartptr<T>&始终有效(并且您也可以更改指针)。
  • 传递为smartptr<T>(通过副本)仅在 smartptr 可复制时才有效。它适用于std::shared_ptr,但不适用于std::unique_ptr,除非您在调用时“移动”它,就像在func(atd::move(myptr))中一样,从而使myptr无效,将指针移动到传递的参数。 (请注意,如果myptr是临时的,则隐式移动。)
  • 传递为smartptr<T>&&(通过移动)强制指针在调用时被移动,强制您明确使用std::move(但需要“移动”以使特定指针有意义)。 / LI>

答案 2 :(得分:4)

如果该函数不会修改或复制指针,则只需使用哑指针。智能指针用于控制对象的生命周期,但该函数不会改变生命周期,因此它不需要智能指针,并且使用哑指针可以为调用者使用的类型提供一些灵活性。

void function(std::string * ptr);

function(my_unique_ptr.get());
function(my_shared_ptr.get());
function(my_dumb_ptr);

unique_ptr无法复制,因此如果必须通过,则必须传递参考。

相关问题