C++ 我可以通过一个独特的ptr';什么是对函数的引用?

C++ 我可以通过一个独特的ptr';什么是对函数的引用?,c++,C++,我可以将唯一的\u ptr引用传递给函数吗?如果不是,我为什么要避免呢 例: void func(唯一\u ptr&ref); main(){ 唯一的_ptr a=std::使_唯一(); fn(a); } 我可以将唯一的\u ptr引用传递给函数吗 是的,unique\u ptr和其他类一样 如果要从函数中变异现有的唯一\u ptr(例如,对其调用.reset()),则应执行此操作 如果只想访问unique\u ptr中的对象,请在函数界面中使用T&或const T&,因此,它们可以独立于u

我可以将唯一的\u ptr引用传递给函数吗?如果不是,我为什么要避免呢

例:

void func(唯一\u ptr&ref);
main(){
唯一的_ptr a=std::使_唯一();
fn(a);
}
我可以将唯一的\u ptr引用传递给函数吗

是的,
unique\u ptr
和其他类一样

如果要从函数中变异现有的
唯一\u ptr
(例如,对其调用
.reset()
),则应执行此操作


如果只想访问
unique\u ptr
中的对象,请在函数界面中使用
T&
const T&
,因此,它们可以独立于
unique\u ptr

向函数传递
std::unique\u ptr
是非常好的,只要您遵守向函数传递常规引用时的相同规则:

  • 基础
    std::unique_ptr
    及其指向的对象必须至少在函数使用该引用时存在
  • 在多线程情况下,必须设置屏障

  • 根据赫伯·萨特的说法:

    通过引用传递唯一\u ptr用于输入/输出唯一\u ptr参数。

    void f( unique_ptr<widget>& ); // (d)
    
    void f(唯一的_ptr&);//(d)
    
    当函数实际接受现有的
    唯一\u ptr
    并可能修改它以引用不同的对象时,这只能用于接受输入/输出
    唯一\u ptr
    。仅仅接受小部件是一种不好的方式,因为它被限制在调用者的特定生存期策略中


    感谢@sgvd

    查看此代码片段,两种将unique_ptr作为函数参数传递的方法。fun1将获得对象的所有权(因此应该从调用方转发),但func2提交的引用是唯一的\u ptr对象将作为引用传递,并且不会被函数修改

    void func1(unique_ptr<Clss>&& moved_obj) // this function takes ownership
    {
        //do something with the moved_obj
    
        moved_obj.reset();
    }
    
    void func2(const unique_ptr<Clss>& ref_obj) // this function takes reference
    {
       unique_ptr<Clss> new_obj = std::make_unique<Clss>(*(ref_obj));
    }
    
    
    int main() {
    
       unique_ptr<Clss> a = std::make_unique<Clss>();
       func1(std::move(a));
    
       unique_ptr<Clss> b = std::make_unique<Clss>();
       func2(b);
    
        return 0;
    }
    
    void func1(唯一的\u ptr&&moved\u obj)//此函数拥有所有权
    {
    //对移动的对象做些什么
    已移动对象重置();
    }
    void func2(const unique_ptr&ref_obj)//此函数引用
    {
    唯一的新对象=标准::使唯一(*(参考对象));
    }
    int main(){
    唯一的_ptr a=std::使_唯一();
    func1(std::move(a));
    唯一的_ptr b=std::使_唯一();
    第2(b)段;
    返回0;
    }
    
    我看到了那些有效且有意义的签名:

    void take_ownership(std::unique_ptr<Clss>);
    // or void take_ownership(std::unique_ptr<Clss>&&);
    
    void use(/*const*/ Clss*);
    // or void use(/*const*/ Clss&);
    
    std::unique_ptr<Clss> create(/*args..*/);
    
    void might_take_ownership(std::unique_ptr<Clss>&);
    
    void-take_-ownership(标准::唯一\u-ptr);
    //或无效取得所有权(std::unique\u ptr&&);
    无效使用(/*const*/Clss*);
    //或无效使用(/*const*/Clss&);
    std::unique_ptr create(/*args..*/);
    void可能拥有所有权(std::unique\u ptr&);
    
    后者可能有道理,但更难推理(就像任何I/O参数一样)


    如果可以的话,选择另一个。

    这个问题很不清楚。你可以问你的编译器这是否可能,如果不可能,那么避免它是没有意义的。编译器允许这样做——但是使用它会出现任何问题吗?我会说这取决于函数,真的。@Leushenko-相反。路过const ref时不应引起注意。您让函数引用对象,甚至让它知道只有一个所有者,而不传递所有权。完全合理。Herb Sutter很好地解释了传递参数的不同方式以及如何解释和选择参数,包括使用对智能指针的引用:向上投票。尽管我必须说,在对象可能无法移动的地方编写
    std::move
    ,感觉很奇怪。如果有
    func1(承认所有权(p))但那既不在这里也不在那里,我只是漫无边际。最好在这里有
    void func2(const Clss&)
    。不应该
    func2(a)be
    func2(b)?再次传递“从指针移动”不是一个好主意。@PaulR:谢谢,拼写错误。EditedGood说您已经添加了链接,但我建议从链接中复制更多的文本,因为不查看链接就很难理解上下文。
    
    void take_ownership(std::unique_ptr<Clss>);
    // or void take_ownership(std::unique_ptr<Clss>&&);
    
    void use(/*const*/ Clss*);
    // or void use(/*const*/ Clss&);
    
    std::unique_ptr<Clss> create(/*args..*/);
    
    void might_take_ownership(std::unique_ptr<Clss>&);