Ste*_*e H 82 c++ c++-faq shared-ptr c++11
如果我声明一个包装在共享指针中的对象:
std::shared_ptr<myClass> myClassObject(new myClass());
Run Code Online (Sandbox Code Playgroud)
然后我想将它作为参数传递给方法:
DoSomething(myClassObject);
//the called method
void DoSomething(std::shared_ptr<myClass> arg1)
{
arg1->someField = 4;
}
Run Code Online (Sandbox Code Playgroud)
以上只是增加了shared_pt的引用计数,一切都很酷吗?还是留下一个悬垂的指针?
你还是应该这样做吗?:
DoSomething(myClassObject.Get());
void DoSomething(std::shared_ptr<myClass>* arg1)
{
(*arg1)->someField = 4;
}
Run Code Online (Sandbox Code Playgroud)
我认为第二种方式可能更有效,因为它只需要复制1个地址(而不是整个智能指针),但第一种方式似乎更具可读性,我不期望推动性能限制.我只是想确保没有危险的东西.
谢谢.
R. *_*des 160
我想传递一个函数的共享指针.你能帮帮我吗?
当然,我可以帮助你.我假设您对C++中的所有权语义有一定的了解.真的吗?
是的,我对这个主题感到相当舒服.
好.
好吧,我只能想出两个理由来shared_ptr争论:
shared_ptrs的操作.你对哪一个感兴趣?
我正在寻找一般答案,所以我实际上对两者都感兴趣.不过,我很好奇你在#2的情况下的意思.
此类函数的示例包括std::static_pointer_cast自定义比较器或谓词.例如,如果您需要从向量中找到所有唯一的shared_ptr,则需要这样的谓词.
啊,当函数实际需要操纵智能指针本身时.
究竟.
在这种情况下,我认为我们应该通过参考.
是.如果它没有改变指针,你想传递const引用.由于您不需要共享所有权,因此无需复制.那是另一种情况.
好的,我知道了.我们来谈谈另一个场景.
您分享所有权的那个?好.你如何分享所有权shared_ptr?
通过复制它.
那么函数需要复制一个shared_ptr,对吗?
明显.所以我通过引用const传递它并复制到局部变量?
不,这是一种悲观情绪.如果通过引用传递,该函数将别无选择,只能手动进行复制.如果按值传递,编译器将在副本和移动之间选择最佳选择并自动执行.所以,传递价值.
好点子.我必须记住" 想要速度?通过价值传递. "这篇文章更频繁.
等等,如果函数存储
shared_ptr在成员变量中,该怎么办?这不会成为冗余副本吗?
该函数可以简单地将shared_ptr参数移动到其存储中.移动a shared_ptr很便宜,因为它不会改变任何引用计数.
啊,好主意.
但我想的是第三种情况:如果你不想操纵
shared_ptr,也不想分享所有权怎么办?
在这种情况下,shared_ptr与功能完全无关.如果你想操纵指针,请指点,让调用者选择他们想要的所有权语义.
我应该通过引用还是通过值来引用指针?
通常的规则适用.智能指针不会改变任何东西.
如果我要复制,则按值传递,如果我想避免复制,则按引用传递.
对.
嗯.我想你又忘了另一个场景.如果我想分享所有权,但仅取决于某种条件,该怎么办?
啊,一个有趣的边缘案例.我不希望经常发生这种情况.但是当它发生时你可以通过值传递并在不需要时忽略副本,或者通过引用传递并在需要时制作副本.
我在第一个选项中冒一个冗余副本的风险,并在第二个选项中失去一个潜在的移动.我不能吃蛋糕也吃吗?
如果你处于真正重要的情况,你可以提供两个重载,一个采用const左值引用,另一个采用右值引用.一个副本,另一个移动.完美转发功能模板是另一种选择.
我认为这涵盖了所有可能的情况.非常感谢你.
Mar*_*som 18
我认为人们不必担心使用原始指针作为函数参数.如果函数不会存储指针或以其他方式影响其生命周期,则原始指针也可以正常工作并表示最小公分母.例如,考虑如何通过值或const引用unique_ptr将a shared_ptr作为参数传递给函数?
void DoSomething(myClass * p);
DoSomething(myClass_shared_ptr.get());
DoSomething(myClass_unique_ptr.get());
Run Code Online (Sandbox Code Playgroud)
作为函数参数的原始指针不会阻止您在调用代码中使用智能指针,这非常重要.
是的,关于shared_ptr<>的整个想法是多个实例可以保存相同的原始指针,并且只有当shared_ptr<>的最后一个实例被销毁时,底层内存才会被释放。
我会避免使用指向shared_ptr<>的指针,因为这违背了你现在再次处理raw_pointers的目的。