[英]How do I pass smart pointers into functions?
将对象传递给函数时,与其他包含动态 memory 的对象一样,适用于智能指针的规则是否相同?
例如,当我将std::vector<std::string>
传递到 function 时,我总是考虑以下选项:
我要更改矢量 object 的 state,但我不希望这些更改在 function 完成后反映出来,也就是制作副本。
void function(std::vector<std::string> vec);
我要更改矢量 object 的 state,我确实希望在 function 完成后反映这些更改,也就是作为参考。
void function(std::vector<std::string> & vec);
这个 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<T>
(通过复制)传递才有效。 它适用于std::shared_ptr
,但不适用于std::unique_ptr
,除非您在调用时“移动”它,例如在func(atd::move(myptr))
,从而使myptr
无效,将指针移动到传递的参数。 (请注意,如果myptr
是临时的,则移动是隐式的)。smartptr<T>&&
(通过移动)传递通过强制您显式使用std::move
(但需要“移动”才能对特定指针有意义)强加要在调用时移动的指针。考虑到 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.