如何传递 unique_ptr<T> 代替原始 *output* 指针参数?
How to pass unique_ptr<T> in place of a raw *output* pointer parameter?
我在外部库中有一个预先存在的函数,它看起来像这样;
bool CreateTheThing(MyThing *& pOut);
简而言之;我给它一个原始指针(通过引用),函数分配内存并将我的指针分配给新分配的对象。当函数returns时,我有责任在我完成后释放内存。
显然,我想将此结果存储到 unique_ptr<MyThing>
中,并避免手动 delete
。
我可以创建一个临时原始指针以用于API调用,并将其传递给unique_ptr
;[=20的构造函数=]
MyThing* tempPtr;
CreateTheThing(tempPtr);
unique_ptr<MyThing> realPtr = unique_ptr<MyThing>(tempPtr);
还有比这更直接的方法吗?一个不需要临时原始指针的?理想情况下,会有一个 unique_ptr
方法以一种可以直接与 CreateTheThing
方法一起工作的方式公开其内部指针?
据我所知,unique_ptr<T>::get()
不允许这样做。它的指针 returns 不是对内部使用指针的引用。
如果您经常使用函数,可以将转换放在函数中。
最好是更改 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;
}
Is there a more direct method than this? One which doesn't require a temporary raw pointer?
没有,没有。
Ideally, there would be a method of unique_ptr which exposes its internal pointer in a way that could work directly with the CreateTheThing method? unique_ptr::get()
does not allow this, to my knowledge.
你的知识是正确的。这将破坏 std::unique_ptr
的全部目的,因此 unique_ptr::get()
是一个 const
函数,指针按值返回。
但是与您的构造函数示例类似,您始终可以使用 std::unique_ptr::reset()
传递外部分配的指针。
另请注意:如果第3方API要求您使用free()
释放内存,您可能需要为std::unique_ptr
提供一个特殊的删除函数。
一次写多行代码可以节省一行代码(可能多次):
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));
我在外部库中有一个预先存在的函数,它看起来像这样;
bool CreateTheThing(MyThing *& pOut);
简而言之;我给它一个原始指针(通过引用),函数分配内存并将我的指针分配给新分配的对象。当函数returns时,我有责任在我完成后释放内存。
显然,我想将此结果存储到 unique_ptr<MyThing>
中,并避免手动 delete
。
我可以创建一个临时原始指针以用于API调用,并将其传递给unique_ptr
;[=20的构造函数=]
MyThing* tempPtr;
CreateTheThing(tempPtr);
unique_ptr<MyThing> realPtr = unique_ptr<MyThing>(tempPtr);
还有比这更直接的方法吗?一个不需要临时原始指针的?理想情况下,会有一个 unique_ptr
方法以一种可以直接与 CreateTheThing
方法一起工作的方式公开其内部指针?
unique_ptr<T>::get()
不允许这样做。它的指针 returns 不是对内部使用指针的引用。
如果您经常使用函数,可以将转换放在函数中。
最好是更改 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;
}
Is there a more direct method than this? One which doesn't require a temporary raw pointer?
没有,没有。
Ideally, there would be a method of unique_ptr which exposes its internal pointer in a way that could work directly with the CreateTheThing method?
unique_ptr::get()
does not allow this, to my knowledge.
你的知识是正确的。这将破坏 std::unique_ptr
的全部目的,因此 unique_ptr::get()
是一个 const
函数,指针按值返回。
但是与您的构造函数示例类似,您始终可以使用 std::unique_ptr::reset()
传递外部分配的指针。
另请注意:如果第3方API要求您使用free()
释放内存,您可能需要为std::unique_ptr
提供一个特殊的删除函数。
一次写多行代码可以节省一行代码(可能多次):
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));