我有代码,我试图将unique_ptr的基础指针传递给通过引用接受指针的方法:
unique_ptr<A> a;
func(a.get());
要调用:
void func(A*& a){ // I am modifying what `a` points to in here
}
但是我收到编译器错误,因为get()
没有返回我期望的只是原始指针。是否有可能实现我在这里想要做的事情?
> 不,这是一件好事。
问题是get()
返回一个右值,而不是对unique_ptr
内部指针的引用。因此,您无法修改它。如果可以的话,你会完全搞砸unique_ptr
的内部状态。
如果要修改unique_ptr
本身,只需传递对本身的引用即可。
通过引用获取指针的函数强烈暗示它可能会重新分配/删除有问题的指针。这意味着它要求所有权责任。调用此类函数的唯一安全方法是从唯一指针中释放指针,并在调用后(可能)重新获取它。
// a currently manages (owns) the pointer
std::unique_ptr<A> a;
// release ownership of internal raw pointer
auto raw = a.release();
// call function (possibly modifying raw)
func(raw);
// (re)claim ownership of whatever func() returns
a.reset(raw);
但是,如果(例如)unique_ptr
有一个特殊的删除器并且该函数没有相应地重新分配对象,这仍然可能是有问题的。此外,如果函数删除指针而不将其设置为 nullptr
则会遇到问题。
这里有一个想法:
template<typename T> struct raw_from_ptr {
raw_from_ptr(T& pointer) : _pointer(pointer), _raw_pointer(null_ptr) {}
~raw_from_ptr() {
if (_raw_pointer != null_ptr)
_pointer.reset(_raw_pointer);
}
raw_from_ptr(pointer_wrapper&& _other) : _pointer(_other._pointer) {
std::swap(_raw_pointer, _other._raw_pointer);
}
operator typename T::pointer*() && { return &_raw_pointer; }
operator typename T::pointer&() && { return _raw_pointer; }
private:
T& _pointer;
typename T::pointer _raw_pointer;
};
template<typename T> raw_from_ptr<T> get_raw_from_ptr(T& _pointer) {
return raw_from_ptr<T>(_pointer);
}
用法:
unique_ptr<A> a;
func(get_raw_from_ptr(a));