将共享指针作为参数传递

2023-12-13

如果我声明一个包含在共享指针中的对象:

std::shared_ptr<myClass> myClassObject(new myClass());

然后我想将它作为参数传递给方法:

DoSomething(myClassObject);

//the called method
void DoSomething(std::shared_ptr<myClass> arg1)
{
   arg1->someField = 4;
}

上面的代码是否只是增加了shared_pt的引用计数并且一切都很酷?或者它会留下一个悬空指针吗?

你还应该这样做吗?:

DoSomething(myClassObject.Get());

void DoSomething(std::shared_ptr<myClass>* arg1)
{
   (*arg1)->someField = 4;
}

我认为第二种方式可能更有效,因为它只需要复制 1 个地址(而不是整个智能指针),但第一种方式似乎更具可读性,并且我预计不会突破性能限制。我只是想确保没有什么危险的事情。

谢谢。


我想将共享指针传递给函数。你能帮我吗?

当然,我可以帮助你。我假设您对 C++ 中的所有权语义有一定的了解。真的吗?

是的,我对这个话题相当满意。

Good.

好吧,我只能想到两个理由shared_ptr争论:

  1. 该函数想要共享该对象的所有权;
  2. 该函数执行一些专门针对shared_ptrs.

您对哪一个感兴趣?

我正在寻找一个普遍的答案,所以我实际上对两者都感兴趣。不过,我很好奇你在案例 #2 中的意思。

此类功能的示例包括std::static_pointer_cast、自定义比较器或谓词。例如,如果需要从向量中查找所有唯一的shared_ptr,则需要这样的谓词。

啊,当函数实际上需要操作智能指针本身时。

Exactly.

在这种情况下,我认为我们应该通过引用传递。

是的。如果它不改变指针,你想通过 const 引用传递。无需复制,因为您不需要共享所有权。那是另一种情况。

好的,我知道了。我们来谈谈另一种情况。

你们分享所有权的那一个?好的。您如何与他人分享所有权shared_ptr?

通过复制它。

然后该函数需要复制一个shared_ptr, 正确的?

明显地。所以我通过对 const 的引用传递它并复制到局部变量?

不,这是一种悲观情绪。如果通过引用传递,函数将别无选择,只能手动进行复制。如果它是按值传递的,编译器将在复制和移动之间选择最佳选择并自动执行。所以,按值传递。

好点子。我必须记住“想要速度吗?按值传递。” 文章更频繁。

等等,如果函数存储了怎么办?shared_ptr例如,在数据成员中?这不会造成多余的副本吗?

该函数可以简单地移动shared_ptr参数进入其存储。移动一个shared_ptr很便宜,因为它不会改变任何引用计数。

啊,好主意。

但我正在考虑第三种情况:如果你不想操纵shared_ptr,也不分享所有权?

在这种情况下,shared_ptr与功能完全无关。如果您想操纵受指点,请获取受指点,并让调用者选择他们想要的所有权语义。

我应该通过引用还是通过值来获取被指点?

通常的规则适用。智能指针不会改变任何东西。

如果我要复制,则按值传递;如果我想避免复制,则按引用传递。

Right.

唔。我想你忘记了另一个场景。如果我想分享所有权,但仅取决于特定条件,该怎么办?

啊,一个有趣的边缘案例。我不希望这种情况经常发生。但是,当发生这种情况时,您可以按值传递并在不需要时忽略副本,或者按引用传递并在需要时创建副本。

我在第一个选项中冒着获得冗余副本的风险,并在第二个选项中失去了潜在的移动。我不能一边吃蛋糕一边吃吗?

如果您处于真正重要的情况,您可以提供两个重载,一个重载采用 const 左值引用,另一个重载采用右值引用。一个复制,另一个移动。完美转发功能模板是另一种选择。

我认为这涵盖了所有可能的情况。非常感谢。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将共享指针作为参数传递 的相关文章

随机推荐