简体   繁体   English

unique_ptr到派生类,作为将unique_ptr带到基类的函数的参数

[英]unique_ptr to a derived class as an argument to a function that takes a unique_ptr to a base class

I'm trying to use a unique_ptr to derived class in a function that takes a unique_ptr to a base class. 我试图在一个函数中使用unique_ptr派生类,该函数将unique_ptr带到基类。 Something like: 就像是:

class Base {};

class Derived : public Base {};

void f(unique_ptr<Base> const &base) {}

…

unique_ptr<Derived> derived = unique_ptr<Derived>(new Derived);
f(derived);

If I understand this answer correctly, this code should work, but it causes the following compile errors: 如果我正确理解了这个答案 ,那么这段代码应该可行,但它会导致以下编译错误:

error C2664: 'f' : cannot convert parameter 1 from 'std::unique_ptr<_Ty>' to 'const std::unique_ptr<_Ty> &' 错误C2664:'f':无法将参数1从'std :: unique_ptr <_Ty>'转换为'const std :: unique_ptr <_Ty>&'

IntelliSense: no suitable user-defined conversion from "std::unique_ptr<Derived, std::default_delete<Derived>>" to "const std::unique_ptr<Base, std::default_delete<Base>>" exists IntelliSense:没有合适的用户定义转换,从“std :: unique_ptr <Derived,std :: default_delete <Derived >>”到“const std :: unique_ptr <Base,std :: default_delete <Base >>”存在

If I change f to take unique_ptr<Derived> const &derived , it works fine, but that's not what I want. 如果我改变f以获取unique_ptr<Derived> const &derived ,它可以正常工作,但这不是我想要的。

Am I doing something wrong? 难道我做错了什么? What can I do to work around this? 我该怎么做才能解决这个问题?

I'm using Visual Studio 2012. 我正在使用Visual Studio 2012。

You have three options: 你有三个选择:

  1. Give up ownership. 放弃所有权。 This will leave your local variable without access to the dynamic object after the function call; 在函数调用之后,这将使您的局部变量无法访问动态对象; the object has been transferred to the callee: 对象已被转移到被调用者:

     f(std::move(derived)); 
  2. Change the signature of f : 更改f的签名:

     void f(std::unique_ptr<Derived> const &); 
  3. Change the type of your variable: 更改变量的类型:

     std::unique_ptr<base> derived = std::unique_ptr<Derived>(new Derived); 

    Or of course just: 或者当然只是:

     std::unique_ptr<base> derived(new Derived); 

    Or even: 甚至:

     std::unique_ptr<base> derived = std::make_unique<Derived>(); 
  4. Update: Or, as recommended in the comments, don't transfer ownership at all: 更新:或者,根据评论中的建议,根本不转让所有权:

     void f(Base & b); f(*derived); 

A possibile solution is to change the type of the argument to be a Base const* , and pass derived.get() instead. 可能的解决方案是将参数的类型更改为Base const* ,然后传递derived.get() There is no transfer of ownership with unique_ptr const<Base>& (and the unique_ptr is not being modified), so changing to a Base const* does not change the meaning. 使用unique_ptr const<Base>& (并且未修改unique_ptr )没有所有权转移,因此更改为Base const*不会改变含义。


Herb Sutter discusses passing smart pointer arguments at length in Smart Pointer Parameters . Herb Sutter讨论了在智能指针参数中传递智能指针参数的过程 An extract from the linked article refers to this exact situation: 链接文章的摘录指的是这种情况:

Passing a const unique_ptr<widget>& is strange because it can accept only either null or a widget whose lifetime happens to be managed in the calling code via a unique_ptr , and the callee generally shouldn't care about the caller's lifetime management choice. 传递const unique_ptr<widget>&并且很奇怪,因为它只能接受null或者生命周期恰好通过unique_ptr在调用代码中管理的widget ,并且被调用者通常不应该关心调用者的生命周期管理选择。 Passing widget* covers a strict superset of these cases and can accept “ null or a widget ” regardless of the lifetime policy the caller happens to be using. 传递widget*涵盖了这些情况的严格超集,并且可以接受“ nullwidget ”,而不管调用者恰好使用的生命周期策略。

I had option #1 of the accepted answer and I still had the same compile error. 我有接受答案的选项#1,我仍然有相同的编译错误。 I banged my head on the wall for over an hour and I finally realized that I had 我把头撞在墙上一个多小时,我终于意识到我有了

class Derived : Base {};

instead of 代替

class Derived : public Base {};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM