【问题标题】:std::unique_ptr with derived class带有派生类的 std::unique_ptr
【发布时间】:2013-06-29 08:43:53
【问题描述】:

我对 c++11 指针有疑问。具体来说,如何将基类的唯一指针转为派生类?

class Base
{
public:
   int foo;
}

class Derived : public Base
{
public:
   int bar;
}

...

std::unique_ptr<Base> basePointer(new Derived);
// now, how do I access the bar member?

这应该是可能的,但我不知道怎么做。每次我尝试使用

basePointer.get()

我最终导致可执行文件崩溃。

提前致谢,如有任何建议,我们将不胜感激。

【问题讨论】:

  • 您能否展示一个完整的(但最少的)导致您的进程崩溃的代码示例? basePointer.get() 单独当然不是问题。
  • @jogojapan 我解决了我的问题。我正在用至少 5 组括号进行一些非常奇怪的转换。我很确定这只是一些愚蠢的事情,但我已经改变了它,不记得我做了什么。不过,Obvlious 船长的回答对我有用。感谢您的所有帮助!

标签: c++ pointers c++11


【解决方案1】:

如果它们是多态类型并且您只需要指向派生类型的指针,请使用dynamic_cast

Derived *derivedPointer = dynamic_cast<Derived*>(basePointer.get());

如果它们不是多态类型,只需要一个指向派生类型的指针,使用static_cast 并希望最好:

Derived *derivedPointer = static_cast<Derived*>(basePointer.get());

如果需要转换包含多态类型的unique_ptr

Derived *tmp = dynamic_cast<Derived*>(basePointer.get());
std::unique_ptr<Derived> derivedPointer;
if(tmp != nullptr)
{
    basePointer.release();
    derivedPointer.reset(tmp);
}

如果需要转换包含非多态类型的unique_ptr

std::unique_ptr<Derived>
    derivedPointer(static_cast<Derived*>(basePointer.release()));

【讨论】:

  • 你确定basePointer.release()没有内存泄漏吗?
  • @Marc 之所以安全是因为release()reset() 都是noexcept,所以除非你在这个函数之外做了一些非常糟糕的事情,否则原始指针总是会在派生的指针将被正确销毁。
  • 这对某些人来说可能很明显,但请注意,您正在从 basePointer 窃取资源,这并不总是您想要的 unique_ptr 转换
  • @Masadow:如果这不是您想要的,那么您就不需要 unique 指针。
  • 答案有问题。是的,static_cast 也支持多态类型。当您不确定强制转换是否有效时,您应该只使用 dynamic_cast(在这种情况下,请测试它是否像您一样返回 null)。
猜你喜欢
  • 1970-01-01
  • 2020-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-18
  • 1970-01-01
  • 2021-07-16
  • 1970-01-01
相关资源
最近更新 更多