繁体   English   中英

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

[英]How do I pass smart pointers into functions?

将对象传递给函数时,与其他包含动态 memory 的对象一样,适用于智能指针的规则是否相同?

例如,当我将std::vector<std::string>传递到 function 时,我总是考虑以下选项:

  1. 我要更改矢量 object 的 state,但我希望这些更改在 function 完成后反映出来,也就是制作副本。

     void function(std::vector<std::string> vec);
  2. 我要更改矢量 object 的 state,我确实希望在 function 完成后反映这些更改,也就是作为参考。

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

     void function(std::vector<std::string> const& vec);

现在这与智能指针的逻辑相同吗? 我什么时候应该考虑移动语义? 关于我应该如何传递智能指针的一些指南是我最想要的。

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

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

智能指针都是关于它们指向的东西的所有权 谁拥有此内存,谁将负责删除它。 unique_ptr代表唯一所有权:只有一段代码拥有此内存。 您可以转让所有权(通过move ),但这样做会失去对内存的所有权。 shared_ptr代表共享所有权。

在所有情况下,在参数列表中使用智能指针代表所有权的转移 因此,如果一个函数接受一个智能指针,那么它将声明该对象的所有权。 如果一个函数不应该拥有所有权,那么它根本就不应该使用智能指针; 使用引用( T& ),或者如果您需要可空性,则使用指针但从不存储它。

如果你给某人一个unique_ptr ,你就给了他们所有权 这意味着,根据唯一所有权的性质,您正在失去对内存的所有权。 因此,几乎没有理由通过值以外的任何东西传递unique_ptr

同样,如果您想共享某个对象的所有权,则传入shared_ptr 您是通过引用还是通过价值来做这件事取决于您。 由于您共享所有权,因此无论如何都会制作副本(大概),因此您不妨按价值获取它。 该函数可以使用std::move其移动到类成员等中。

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

void function(std::string * ptr);

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

unique_ptr不能被复制,所以如果你必须传递它,你必须传递一个引用。

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

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

  • 作为const smartptr<T>&传递始终有效(并且您不能更改指针,但可以更改它指向的状态)。
  • 作为smartptr<T>&传递始终有效(您也可以更改指针)。
  • 仅当smartptr可复制时,作为smartptr<T> (通过复制)传递才有效 它适用于std::shared_ptr ,但不适用于std::unique_ptr ,除非您在调用时“移动”它,例如在func(atd::move(myptr)) ,从而使myptr无效,将指针移动到传递的参数。 (请注意,如果myptr是临时的,则移动是隐式的)。
  • 作为smartptr<T>&& (通过移动)传递通过强制您显式使用std::move (但需要“移动”才能对特定指针有意义)强加要在调用时移动的指针。
  • 我知道在 C++ 中问这个问题的人比我知识渊博并且这个问题有一些完美的答案,但我相信这个问题最好以一种不会吓到 C++ 的人的方式回答,尽管它可能会得到一点复杂,这是我的尝试:

考虑到 C++ 中只有一种类型的智能指针,它是shared_ptr ,所以我们有这些选项将它传递给 function:

1 - 按void f(std::shared_ptr<Object>);

2 - 通过引用void f(std::shared_ptr<Object>&);

最大的区别是,第一个借给所有权,第二个让你操纵所有权。

进一步阅读和细节可以在这个链接之前帮助过我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM