首页 > 解决方案 > 销毁时悬空引用的具体案例

问题描述

这是我无法更改且必须适应的代码:

struct SomeInterface
{
   ...
};

struct SomeClass
{
   SomeClass(SomeInterface& iface) : iface(iface) {}
   SomeInterface& iface;
   ...
};

我必须编写一个函数,我将从其他函数中获取并SomeInterface返回指向. 问题是,将在该函数堆栈上创建unique_ptr ,因此从它返回后引用将无效。我编写了一个简单的包装类,它继承自并扩展它以将 unique_ptr 保存到.SomeClassSomeInterfaceSomeInterfaceSomeClassSomeInterface

std::unique_ptr<SomeClass> getSomeClass()
{
   struct SomeClassWrapper : public SomeClass
   {
      SomeClassWrapper(std::unique_ptr<SomeInterface> iface) 
        : SomeClass(*iface), 
          iface(std::move(iface)) {}

      std::unique_ptr<SomeInterface> iface;
   };

   std::unique_ptr<SomeInterface> iface = getIfaceFromSomewhere();

   return std::unique_ptr<SomeClass>(std::make_unique<SomeClassWrapper>(std::move(iface))
}

这解决SomeInterface's了终身问题......几乎。不幸的是,SomeClassWrapper在成员变量iface的销毁过程中首先被销毁,所以基类有一个短暂SomeClass的引用。

如何在没有这个问题的情况下达到我想要的结果?

干杯

标签: c++

解决方案


将 移动unique_ptr到首先构造并最后销毁的基类中:

struct SomeClassWrapperPtrMember {
    std::unique_ptr<SomeInterface> iface;
};

struct SomeClassWrapper : public SomeClassWrapperPtrMember, SomeClass
{
     SomeClassWrapper(std::unique_ptr<SomeInterface> iface) 
        : SomeClassWrapperPtrMember{std::move(iface)},
          SomeClass(*(this->iface)) {}
};

推荐阅读