Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将共享指针作为参数传递_C++_C++11_Shared Ptr_C++ Faq - Fatal编程技术网

C++ 将共享指针作为参数传递

C++ 将共享指针作为参数传递,c++,c++11,shared-ptr,c++-faq,C++,C++11,Shared Ptr,C++ Faq,如果我声明一个封装在共享指针中的对象: std::shared_ptr<myClass> myClassObject(new myClass()); std::shared_ptr myClassObject(new myClass()); 然后我想把它作为参数传递给一个方法: DoSomething(myClassObject); //the called method void DoSomething(std::shared_ptr<myClass> arg1)

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

std::shared_ptr<myClass> myClassObject(new myClass());
std::shared_ptr myClassObject(new myClass());
然后我想把它作为参数传递给一个方法:

DoSomething(myClassObject);

//the called method
void DoSomething(std::shared_ptr<myClass> arg1)
{
   arg1->someField = 4;
}
DoSomething(myClassObject);
//被调用的方法
无效剂量测量(标准::共享剂量arg1)
{
arg1->someField=4;
}
上述操作是否只是增加了共享节点的引用计数,并且一切正常?还是会留下一个悬空的指针

你还应该这么做吗

DoSomething(myClassObject.Get());

void DoSomething(std::shared_ptr<myClass>* arg1)
{
   (*arg1)->someField = 4;
}
DoSomething(myClassObject.Get());
无效剂量测量(标准::共享剂量*arg1)
{
(*arg1)->someField=4;
}
我认为第二种方法可能更有效,因为它只需要复制一个地址(与整个智能指针相反),但第1种方法看起来更可读,而且我预计不会超出性能限制。我只是想确定它没有什么危险


谢谢。

是的,关于共享\u ptr的整个想法是,多个实例可以持有相同的原始指针,并且只有在共享\u ptr的最后一个实例被销毁时,基础内存才会被释放


我会避免使用指向共享\u ptr的指针,因为这样做会破坏目的,因为您现在再次处理原始\u指针。

在第一个示例中,通过值传递是安全的,但有一个更好的习惯用法。尽可能通过常量引用传递-即使在处理智能指针时,我也会说是。您的第二个示例并没有完全损坏,但它非常
。愚蠢的,没有完成任何事情,挫败了智能指针的一部分,当你试图取消引用和修改东西时,会让你陷入一个痛苦的错误世界

我想向函数传递一个共享指针。你能帮我吗

当然,我可以帮你。我假设你对C++中的所有权语义有一些了解。这是真的吗

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

好的,我只能想到两个理由来接受一个
shared_ptr
参数:

  • 函数想要共享对象的所有权
  • 该函数执行特定于
    shared_ptr
    s的操作
  • 你对哪一个感兴趣

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

    此类函数的示例包括
    std::static\u pointer\u cast
    、自定义比较器或谓词。例如,如果需要从一个向量中查找所有唯一的shared_ptr,则需要这样一个谓词

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

    没错

    那样的话,我想我们应该参考一下

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

    好的,明白了。让我们谈谈另一种情况

    你分享所有权的那个?好啊您如何与
    共享\u ptr
    共享所有权

    通过复制它

    然后该功能需要复制一份
    共享\u ptr
    ,对吗

    很明显。所以我通过一个对const的引用来传递它,然后复制到一个局部变量

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

    说得好。我必须更经常地记住那篇文章

    等等,例如,如果函数将
    共享的ptr
    存储在成员变量中,该怎么办?这不是多余的副本吗

    该函数只需将
    shared_ptr
    参数移动到其存储器中即可。移动
    共享\u ptr
    成本低廉,因为它不会改变任何引用计数

    啊,好主意

    但我想到了第三种情况:如果您不想操纵
    共享的\u ptr
    ,也不想共享所有权,该怎么办

    在这种情况下,
    shared_ptr
    与函数完全无关。如果您想要操纵指针对象,那么获取一个指针对象,让调用方选择他们想要的所有权语义

    我应该通过引用还是通过值来获取指针

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

    如果要复制,请按值传递;如果要避免复制,请按引用传递

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

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

    我在第一个选项中冒着一个多余副本的风险,在第二个选项中失去一个潜在的移动。我不能既吃蛋糕又吃它吗

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

    我认为这涵盖了所有可能的情况。多谢各位


    我认为人们不必要地害怕使用原始指针作为函数参数。如果函数不打算存储指针或以其他方式影响其生存期,则原始指针也可以工作,并表示最低公分母。例如,考虑如何将<代码> UnQuyPPTR <代码>传递到一个函数中,该函数以<代码> SydDypTr>代码>作为参数,无论是值还是const引用?

    void DoSomething(myClass * p);
    
    DoSomething(myClass_shared_ptr.get());
    DoSomething(myClass_unique_ptr.get());
    
    作为函数参数的原始指针不会阻止您在调用代码中使用智能指针,这才是真正重要的。

    在函数中
    DoSomething
    您正在更改数据membe