我正在尝试创建一个需要auto_ptr
到Base
类的函数,我想用auto_ptr
到Derived
类来调用它。但是我没能完成它。
我尝试过使用它而没有引用:
void function(std::auto_ptr<Base> ptr);
std::auto_ptr<Derived> derivedPtr( new ... )
function(derivedPtr); // error: #348: more than one user-defined conversion from
// "std::auto_ptr<Derived>" to "std::auto_ptr<Base>" applies
并参考:
void function(std::auto_ptr<Base>& ptr);
std::auto_ptr<Derived> derivedPtr( new ... )
function(derivedPtr); //error: #304: no instance of overloaded function "function"
// matches the argument list
编辑:
我知道auto_ptr已弃用,但我只能访问C++03
且无法访问boost
。所以如果答案将集中在问题本身上,我将不胜感激:)我也理解采用引用的函数和按值的auto_ptr的区别。在我的实际代码中,该函数取得了auto_ptr
的所有权,因此如果我可以从Derived
转换为Base
工作,则两者都可以。
答案 0 :(得分:5)
您正在尝试auto_ptr
按值和参考,这是完全不同的事情。按值调用意味着,您将所有权转移到函数中,因为auto_ptr
在复制时执行此操作。通过引用调用意味着函数外只有auto_ptr
来保持所有权。
由于这种差异非常不直观,{2011年标准中已经弃用了auto_ptr
,作者一直在劝阻使用auto_ptr
更长时间。简而言之:
根本不要使用auto_ptr
。
如果要将所有权转移到函数中,请使用unique_ptr
;如果要将其保留在函数外部,请使用引用或普通指针。这取决于你的实际情况。
更新,因为你提到你必须在不使用boost的情况下使用C ++ 03,所以有一个针对C ++ 03的unique_ptr实现:http://howardhinnant.github.io/unique_ptr03.html 它使用了一些可以轻松手写的增强功能,因此无需使用增强功能即可将其移植到平台上。
答案 1 :(得分:4)
你可以毫不含糊地投射:
function(static_cast<std::auto_ptr<Base> >(derivedPtr));
请注意,要使其正常工作,Base
必须具有虚拟析构函数。否则代码具有未定义的行为。
模棱两可的原因就像Arne在他的回答中所说的那样 - 调用者对function
是否接受值或引用并不明显,因此对于调用者来说,他们的{{1}是否不明显将通过调用释放或不释放,如果它被释放,它是否被转换为可以正确auto_ptr
指针的类型。模棱两可的转换AFAIK就是为了阻止你编写这么难的代码。通过强制转换,您可以在delete
被释放的调用代码中明确显示它。
答案 2 :(得分:1)
手动管理内存比使用auto_ptr
更好,因为它的使用非常充满错误。
最好使用工业强度替代:最糟糕的是,检查自由主义boost
liscense并确定你是否可以编写自己的克隆。
失败,写下你自己的替换owning_ptr
。同时创建ownomg_ptr_transfer
班级template
。在owning_ptr
上阻止复制构造构造,从owning_ptr_transfer
启用隐式转换,该转换采用底层限制。有一个自由的函数或方法将底层指针移动到传输对象。
从本质上讲,如果必须,请使用C ++ 03编写自己的unique_ptr
。
如果您不使用别人的解决方案,也不会自己编写解决方案,那么只需手动操作内存即可。 auto_ptr
不值得:与unique_ptr
相比,它不仅仅是次优的,它实际上是有害的:它的目的是使内存管理更容易,而且它更容易出错。这是一次实验,但失败了。