使用 std::<T>unique_ptr& 代替 std::unique_ptr 有什么好处<T>吗?
Are there any advantages of using std::unique_ptr<T>& instead of std::unique_ptr<T>?
使用std::unique_ptr<T>&
而不是std::unique_ptr<T>
有什么好处吗?例如,在函数参数中?
有几种不同的情况
- 您想将所有权转移到函数
- 使用
std::unique_ptr<T>
- 使用
- 您希望允许函数修改指针
- 使用
std::unique_ptr<T> &
- 使用
- 您希望允许函数修改指针对象
- 使用
T &
,并在调用站点取消引用 - 如果指针可能为null,请改用
T *
并在调用站点调用unique_ptr::get
- 使用
- 您希望允许函数观察指针对象
- 使用
const T &
,并在调用站点取消引用 - 如果指针可能为null,请改用
const T *
并在调用站点调用unique_ptr::get
- 使用
- 您希望允许函数具有指针对象的副本
- 使用
T
,并在调用站点取消引用
- 使用
- 您在
unique_ptr<T>
的集合上有一个ranged for循环(或<algorithm>
调用(,并且希望观察这些值,但没有ranges::indirect
(或类似的(- 使用
auto &
,并知道它被推断为std::unique_ptr<T> &
(如果集合是const
,则为const std::unique_ptr<T> &
(,因此必须在循环体中取消引用
- 使用
由于std::unique_ptr
在设计中无法复制,因此采用std::unique_ptr<T>
的函数只能通过将指针的所有权传递给函数来调用(即移动构造(。调用代码将无法再访问指针。
使用std::unique_ptr<T>&
,您允许函数"查看"指针并访问其成员,但调用代码保留所有权,因此仍然可以自己使用它。
std::unique_ptr只能移动,因此如果按值传递unique_ptr-则无法在函数调用后提取其内容,但如果按引用传递,则可以检索值。以下是相同的示例代码:
#include <iostream>
#include <memory>
void changeUniquePtrReference(std::unique_ptr<int>& upr)
{
*upr = 9;
}
void changeUniquePtrValue(std::unique_ptr<int> upv)
{
*upv = 10;
}
int main()
{
std::unique_ptr<int> p(new int);
*p =8;
std::cout<<"value of p is "<<*p<<std::endl;
changeUniquePtrReference(p);
std::cout<<"value of p is "<<*p<<std::endl;
changeUniquePtrValue(std::move(p));
std::cout<<"Memory deallocated so below line will crash.. "<<std::endl;
std::cout<<"value of p is "<<*p<<std::endl;
return 0;
}
这两种变体不同,适用于特定情况。
如果您的函数采用std::unique_ptr<T>
,这意味着您将接管托管对象的所有权,并将其删除或保存到其他地方。
如果使用std::unique_ptr<T> &
,则不会获得所有权,但可以更改指针指向的内容,例如将其重置为其他对象。
如果不打算更改指针本身,则只需传递一个T&
或一个常量T&
,具体取决于是否计划修改对象。传递const std::unique_ptr<T> &
是没有用的,因为这并不能使您比传递T&
做更多的事情,还有潜在的额外间接性和对参数的不必要限制的缺点。
Herb Sutter解释了将智能指针传递到具有所有可能变体的函数的所有利弊。请阅读文章了解更多信息,它真的很好:
简而言之,除非您的预期行为是放弃指针的所有权,否则在没有引用的情况下将unique_ptr
传递给函数是没有意义的。!
就我个人而言,我只看到一种情况,您应该传递对unique_ptr的引用:即您正在调用的方法可能在内部决定删除或放弃对象。这种情况应该非常罕见,因为所有者放弃了所有权的决定,老实说,这不是一个好的设计。
如果子对象总是夺走所有权或删除对象,则参数类型应为unique_ptr值并立即传递所有权。
如果子对象只是想访问指针内容,那么参数应该是原始指针。你可以为const unique_ptr reference
提出一个论点,这会阻止你发布它,但这有什么意义?如果你觉得你需要一个超出raw的约定,你可以装饰这个原始指针类型的名称,这样你就知道你不拥有它。
- CLANG 编译器 说:变量"PTR"可能未初始化
- EASTL矢量<向量<int>>连续的
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- C++中的指针否定 (!ptr == NULL)
- 从const ptr*转换为ptr*时出现问题
- 这是MSVC 2013中具有共享PTR的单例的正确实现吗?
- 对唯一 ptr 无效读取的引用向量
- C++ 类型转换基础 PTR 到派生 PTR 保存在引用类中
- 如何使用非类型参数传递模板化类的 Ref 或 Ptr