如何传递unique_ptr<T>代替原始*输出*指针参数?

How to pass unique_ptr<T> in place of a raw *output* pointer parameter?

本文关键字:原始 输出 参数 指针 unique 何传递 ptr lt gt      更新时间:2023-10-16

我在外部库中具有A

bool CreateTheThing(MyThing *& pOut);

简而言之;我给它一个原始的指针(通过引用(,该功能分配内存并将我的指针分配给新分配的对象。当功能返回时,我完成记忆是我的责任。

显然,我想将此结果存储到unique_ptr<MyThing>中,然后避免手册delete

i 可以创建一个临时的原始指针,以与API调用一起使用,然后将其传递到unique_ptr;

的构造函数中
MyThing* tempPtr;
CreateTheThing(tempPtr);
unique_ptr<MyThing> realPtr = unique_ptr<MyThing>(tempPtr);

有比这更直接的方法吗?一个不需要临时的原始指针?理想情况下,将有一种unique_ptr的方法以直接与CreateTheThing方法合作的方式公开其内部指针?

据我所知,

unique_ptr<T>::get()不允许这样做。它返回的指针不是对内部使用指针的引用。

您可以通过编写许多代码来保存一行(可能多次(:

class Wrapper
{
  std::unique_ptr<MyThing> &u;
  MyThing *p;
public:
  Wrapper(std::unique_ptr<MyThing> &u) : u(u), p() {}
  operator MyThing* & ()
  { return p; }
  ~Wrapper()
  { u.reset(p); }
};

用法:

std::unique_ptr<MyThing> u;
CreateTheThing(Wrapper(u));

有比这更直接的方法吗?一个不需要临时的原始指针?

不,没有。

理想情况下,将有一种唯一的_ptr方法,它可以直接与CreateThing方法合作,以揭示其内部指针?据我所知,unique_ptr::get()不允许这样做。

您的知识是正确的。这将破坏std::unique_ptr的全部目的,因此unique_ptr::get()const函数,指针由值返回。

但是,与您的构造函数相似,您可以随时使用std::unique_ptr::reset()传递外部分配的指针。

另外,请注意:如果第三方API要求您使用free()发布内存,则可能需要为std::unique_ptr提供特殊的Deleter函数。

如果您经常使用该功能,则可以将转换放在函数中。

最好是更改API,但这也可以工作。

inline std::unique_ptr<MyThing> CreateTheThing()
{
  MyThing* p;
  if (CreateTheThing(p))
  {
    return std::unique_ptr<MyThing>(p);
  }
  return std::unique_ptr<MyThing>();
}

您还可以使此重载以使重构更加容易:

inline bool CreateTheThing(std::unique_ptr<MyThing>& ptr)
{
    try 
    {
        MyThing* p;
        if (CreateTheThing(p))
            ptr = std::unique_ptr<MyThing>(p);
        else
            return false;
    }
    catch (std::bad_alloc&)
    {
        return false;
    }
    return true;
}