传递共享指针作为参数 [英] Passing shared pointers as arguments

查看:188
本文介绍了传递共享指针作为参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

  DoSomething(myClassObject); 

//被调用的方法
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地址(而不是整个智能指针),但第一种方式似乎更可读,我不预期推动性能限制。

解决方案

/ div>


我想传递一个函数的共享指针。请告诉我如何做。


我只能想到两个原因需要一个 shared_ptr 参数:


  1. 该函数想要共享对象的所有权;

  2. 函数执行某些在 shared_ptr 上工作的操作。

你感兴趣吗?


我在寻找一个一般的答案,所以我实际上对这两个感兴趣。


这种函数的示例包括 std :: static_pointer_cast ,自定义比较器或谓词。例如,如果你需要从向量中找到所有唯一的shared_ptr,你需要这样一个谓词。


以操作智能指针本身。






$ b b

在这种情况下,我认为我们应该通过参考。


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


好吧,让我们来谈谈其他情况。


你分享所有权的那个?好。如何通过 shared_ptr 共享所有权?


>

然后函数需要复制一个 shared_ptr p>


显然。所以我通过一个引用const并复制到一个局部变量?


不,这是一个pessimization。如果通过引用传递,函数将不得不手动进行复制。如果它通过值,编译器将选择一个复制和移动之间的最佳选择,并自动执行。所以,传递价值。


好点。我必须记住,想要速度?按值传递



等等,如果函数在成员变量中存储 shared_ptr ,例如?


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


啊,好主意。



但我想到第三种情况:如果你不想操作 shared_ptr ,也不分享所有权?


在这种情况下, shared_ptr 与函数完全无关。


如果你想操作pointee,请选择一个pointee,让呼叫者选择他们想要的所有权语义。通过引用或按值?


通常的规则适用。智能指针不会更改任何内容。


如果我要复制,请按值传递,如果我想避免复制


右。


。我想你忘了另一种情况。如果我想分享所有权,但只根据某个条件,该怎么办?


Ah,一个有趣的边缘情况。我不期望经常发生。但是当它发生时,你可以通过值传递,忽略副本,如果你不需要它,或通过引用和复制,如果你需要它。


我有一个冗余副本在第一个选项,并在第二个失去一个潜在的移动。


如果你在这种情况下真的很重要,你可以提供两个重载,一个取const常量引用,另一个取右值引用。一个副本,另一个移动。完美转发功能模板是另一个选项。


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



If I declare an object wrapped in a shared pointer:

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

then I wanted to pass it as an argument to a method:

DoSomething(myClassObject);

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

Does the above simply increment the shared_pt's reference count and everything is cool? Or does it leave a dangling pointer?

Are you still supposed to do this?:

DoSomething(myClassObject.Get());

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

I think that the 2nd way may be more efficient because it only has to copy 1 address (as opposed to the whole smart pointer), but the 1st way seems more readable and I do not anticipate pushing performance limits. I just want to make sure there's not something dangerous about it.

Thank you.

解决方案

I want to pass a shared pointer to a function. Tell me how to do that.

I can only think of two reasons to take a shared_ptr argument:

  1. The function wants to share ownership of the object;
  2. The function does some operation that works specifically on shared_ptrs.

Which one are you interested in?

I'm looking for a general answer, so I'm actually interested in both. I'm curious about what you mean in case #2, though.

Examples of such functions include std::static_pointer_cast, custom comparators, or predicates. For example, if you need to find all unique shared_ptr from a vector, you need such a predicate.

Ah, when the function actually needs to manipulate the smart pointer itself.

Exactly.

In that case, I think we should pass by reference.

Yes. And if it doesn't change the pointer, you want to pass by const reference. There's no need to copy since you don't need to share ownership. That's the other scenario.

Ok, got it. Let's talk about the other scenario.

The one where you share the ownership? Ok. How do you share ownership with shared_ptr?

By copying it.

Then the function will need to make a copy of a shared_ptr, correct?

Obviously. So I pass it by a reference to const and copy to a local variable?

No, that's a pessimization. If it is passed by reference, the function will have no choice but to make the copy manually. If it is passed by value the compiler will pick the best choice between a copy and a move and perform it automatically. So, pass by value.

Good point. I must remember that "Want Speed? Pass by Value." article more often.

Wait, what if the function stores the shared_ptr in a member variable, for example? Won't that make a redundant copy?

The function can simply move the shared_ptr argument into its storage. Moving a shared_ptr is cheap because it doesn't change any reference counts.

Ah, good idea.

But I'm thinking of a third scenario: what if you don't want to manipulate the shared_ptr, nor to share ownership?

In that case, shared_ptr is completely irrelevant to the function. If you want to manipulate the pointee, take a pointee, and let the callers pick what ownership semantics they want.

And should I take the pointee by reference or by value?

The usual rules apply. Smart pointers don't change anything.

Pass by value if I'm going to copy, pass by reference if I want to avoid a copy.

Right.

Hmm. I think you forgot yet another scenario. What if I want to share ownership, but only depending on a certain condition?

Ah, an interesting edge case. I don't expect that to happen often. But when it happens you can either pass by value and ignore the copy if you don't need it, or pass by reference and make the copy if you need it.

I risk one redundant copy in the first option, and lose a potential move in the second. Can't I eat the cake and have it too?

If you're in a situation where that really matters, you can provide two overloads, one taking a const lvalue reference, and another taking an rvalue reference. One copies, the other moves. A perfect-forwarding function template is another option.

I think that covers all the possible scenarios. Thank you very much.

这篇关于传递共享指针作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆