函数采用<Base>可以接受 std::auto_ptr 的 std::auto_ptr<Derived>



我正在尝试创建一个函数,该函数需要auto_ptrBase类,我想用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工作,那么两者都很好。

您正在尝试按值和引用auto_ptr,这是完全不同的事情。按值调用意味着您将所有权转移到函数中,因为auto_ptr副本上执行此操作。通过引用调用意味着只有保留所有权的函数外部的auto_ptr

由于这种差异非常不直观,因此auto_ptr在 2011 年的标准中已被弃用,作者一直在阻止使用auto_ptr更长的时间。总之:

根本不要使用auto_ptr

如果要将所有权转移到函数中,请使用unique_ptr;如果要将其保留在函数外部,请使用引用或纯指针。这取决于您的实际情况。

更新:由于您提到必须在没有 boost 的情况下使用 C++03,因此 C++03 有一个unique_ptr实现:http://howardhinnant.github.io/unique_ptr03.html 它使用了一些可以轻松手写的增强功能,因此应该可以将其移植到您的平台而无需使用增强。

您可以毫不含糊地进行投射:

function(static_cast<std::auto_ptr<Base> >(derivedPtr));

请注意,要使其正常工作,Base必须具有虚拟析构函数。否则,代码具有未定义的行为。

模棱两可的原因是 Arne 在他的回答中所说 - 调用方并不明显function采用值还是引用,因此调用方并不明显,他们的auto_ptr是否会通过调用被释放,如果释放,它是否转换为可以正确delete指针的类型。模棱两可的转换 AFAIK 可以阻止您编写如此困难的代码。通过强制转换,可以在调用代码中显式发布derivedPtr

手动管理内存比使用内存auto_ptr更好,因为它的使用充满了错误。

最好使用工业实力替代品:在最坏的情况下,检查自由主义boost,并确定是否可以编写自己的克隆。

法利姆,写下你自己的改编owning_ptr. 同时创建一个ownomg_ptr_transfertemplate。 在owning_ptr上块复制构造,位启用从owning_ptr_transfer隐式转换,这需要底层的poimter。 具有将基础指针移动到传输对象的自由函数或方法。

本质上,如果必须,请使用 C++03 编写自己的unique_ptr

如果你不会使用别人的解决方案,也不会编写自己的解决方案,那么只需手动记忆即可。auto_ptr不值得:与unique_ptr相比,它不仅是次优的,它实际上是有害的:其目的是使内存管理更容易,相反,它使它更容易出错。 这是一个实验,它失败了。

最新更新