svi*_*ick 57 c++ unique-ptr c++11 visual-studio-2012
我试图unique_ptr
在一个unique_ptr
带有基类的函数中使用一个派生类.就像是:
class Base {};
class Derived : public Base {};
void f(unique_ptr<Base> const &base) {}
…
unique_ptr<Derived> derived = unique_ptr<Derived>(new Derived);
f(derived);
Run Code Online (Sandbox Code Playgroud)
如果我正确理解了这个答案,那么这段代码应该可行,但它会导致以下编译错误:
错误C2664:'f':无法将参数1从'std :: unique_ptr <_Ty>'转换为'const std :: unique_ptr <_Ty>&'
IntelliSense:没有合适的用户定义转换,从"std :: unique_ptr <Derived,std :: default_delete <Derived >>"到"const std :: unique_ptr <Base,std :: default_delete <Base >>"存在
如果我改变f
采取unique_ptr<Derived> const &derived
,它工作正常,但这不是我想要的.
难道我做错了什么?我该怎么做才能解决这个问题?
我正在使用Visual Studio 2012.
Ker*_* SB 61
你有三个选择:
放弃所有权.在函数调用之后,这将使您的局部变量无法访问动态对象; 对象已被转移到被调用者:
f(std::move(derived));
Run Code Online (Sandbox Code Playgroud)更改签名f
:
void f(std::unique_ptr<Derived> const &);
Run Code Online (Sandbox Code Playgroud)更改变量的类型:
std::unique_ptr<base> derived = std::unique_ptr<Derived>(new Derived);
Run Code Online (Sandbox Code Playgroud)
或者当然只是:
std::unique_ptr<base> derived(new Derived);
Run Code Online (Sandbox Code Playgroud)
甚至:
std::unique_ptr<base> derived = std::make_unique<Derived>();
Run Code Online (Sandbox Code Playgroud)更新:或者,根据评论中的建议,根本不转让所有权:
void f(Base & b);
f(*derived);
Run Code Online (Sandbox Code Playgroud)Dav*_*vid 27
我有已接受答案的选项 #1,但我仍然遇到相同的编译错误。我把头撞在墙上一个多小时,我终于意识到我有
class Derived : Base {};
Run Code Online (Sandbox Code Playgroud)
代替
class Derived : public Base {};
Run Code Online (Sandbox Code Playgroud)
可能的解决方案是将参数的类型更改为a Base const*
,然后传递derived.get()
.没有所有权转让unique_ptr const<Base>&
(并且unique_ptr
没有被修改),因此改为a Base const*
不会改变含义.
Herb Sutter讨论了在智能指针参数中传递智能指针参数的过程.链接文章的摘录指的是这种情况:
传递a
const unique_ptr<widget>&
很奇怪,因为它只能接受其中任何一个null
或者widget
其生命周期恰好通过a来管理在调用代码中unique_ptr
,并且被调用者通常不应该关心调用者的生命周期管理选择.传递widget*
涵盖了这些情况的严格超集,并且可以接受"null
或widget
",而不管呼叫者恰好使用的生命周期策略.