c++ - CppCoreGuidlines R.33 为什么通过引用传递`unique_ptr`?
问题描述
CppCoreGuidlines规则 R.33建议
带一个
unique_ptr<widget>&
参数来表示一个函数重新安装小部件。原因
unique_ptr
以这种方式使用既记录并强制执行函数调用的重新定位语义。注意“重新安装”的意思是“使指针或智能指针指向不同的对象。”</p>
我不明白为什么当 reseat 意味着“使指针或智能指针指向不同的对象”时我们应该通过引用传递。</p>
当函数的目的是重新设置/更改指针指向的基础对象时,我们不是以这种方式从调用者那里窃取所有权,因此应该传递unique_ptr
按值,从而移动它并转移所有权吗?
有没有一个例子可以解释为什么unique_ptr
推荐通过引用传递?
解决方案
当函数的目的是重置/更改指针指向的底层对象时,我们不是这样从调用者那里窃取所有权吗
不,当我们“重新定位”一个指针时,或者当我们改变指向的对象时,我们都没有获得指针的所有权,即我们没有转移所有权。
是否有一个示例可以解释为什么建议通过引用传递 unique_ptr ?
下面是一个“重置”唯一指针的函数示例:
void reseat(std::unique_ptr<widget>& ptr) {
ptr = std::make_unique<widget>();
}
如果您尝试使用对 const 的引用,则根本无法编译。如果您尝试使用非引用参数,则参数指针将不会被修改,因此行为不会如预期那样。调用者将被迫移动他们的指针,使其始终为空。
您可以修改示例以使用指向唯一指针的指针,但建议使用引用,因为不可能错误地传递 null。引用包装器也可以工作,但它会不必要地复杂。
如果我们让它指向其他地方,它之前指向的对象会发生什么?
如果一个唯一的指针指向非空的东西,那么让它指向别处将导致先前指向的对象被删除。
在这种情况下我们不是在泄漏内存吗?
不。
请注意,示例很简单,以便于理解。通常我不建议编写这样的函数,而是考虑编写一个返回新唯一指针的函数,并让调用者自己“重新定位”指针。但这取决于细节。
推荐阅读
- c# - 在变量中存储多行
- node.js - npm WARN saveError EPERM: operation not allowed, rename 'C:\...\package.json.3542172463' -> 'C:\...\package.json'
- java - 比较Java中的时间对象
- marklogic - xdmp:diacritic-less 给出意想不到的结果
- odoo - 如何编写python代码来获取Odoo计算字段中特定时期之间所有销售订单的总和?
- postgresql - 如何在 Pgadmin4 中创建服务器?
- java - 使用 jodconvertor 将 doc 转换为 pdf 时出现连接拒绝错误
- javascript - FullCalendar 不通过 AJAX/JSON 呈现所有事件
- php - MVC:哪个 MVC 层对于这种方法是正确的?
- javascript - 循环遍历数组出错