我在编译这段代码时遇到了问题:
void MyClass::MyMethod(Type * new_ptr)
{
myInternalUniquePtr_->swap(std::unique_ptr<Type>(new_ptr));
}
ReSharper 表示将右值引用绑定(bind)到左值引用是非标准 Microsoft C++ 扩展
。这似乎是正确的,因为我无法在 GCC 中编译它,例如。
我已将代码更改为:
void MyClass::MyMethod(Type * new_ptr)
{
myInternalUniquePtr_->reset(new_ptr);
}
这可以接受吗?
更新: reset
正在调用旧 ptr 的删除器。 MS extension是否调用了之前值的deleter?
Update2: 检查,是的,它删除了旧的 ptr 值,但不是在 swap
本身,而是在函数存在之后(感谢 James)
最佳答案
reset
is calling deleter of old ptr. Does MS extension call the deleter of the previous value?
std::unique_ptr::swap
在调用中涉及的对象之间相互转移存储指针的所有权。因此,myInternalUniquePtr
拥有的指针与临时对象交换,std::unique_ptr<Type>(new_ptr)
,其生命周期结束于它所属的完整表达式的末尾。对于函数调用语句,这意味着在 ;
点销毁此临时文件, 表示原来存放在myInternalUniquePtr_
中的指针在语句执行后被释放(由那个临时的析构函数)。事实上,VC++ 允许一个纯右值临时值被一个非常量左值引用(这是一个不符合规范的特性)所绑定(bind),这应该不会影响上述行为。
替换:
myInternalUniquePtr_->reset(new_ptr);
有效。但是,调用者不清楚 MyMethod
内部发生了什么.更好的选择是强制调用者显式传递 unique_ptr
。 ,这很明显该函数拥有该指针的所有权,并且它不应该指向,例如,一个数组。
void MyClass::MyMethod(std::unique_ptr<Type> new_ptr)
{
myInternalUniquePtr_ = std::move(new_ptr);
}
关于c++ - 交换 unique_ptr(非标准 Microsoft C++ 扩展),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32558493/