首页 > 解决方案 > CppCoreGuidlines R.33 为什么通过引用传递`unique_ptr`?

问题描述

CppCoreGuidlines规则 R.33建议

带一个unique_ptr<widget>&参数来表示一个函数重新安装小部件。

原因unique_ptr以这种方式使用既记录并强制执行函数调用的重新定位语义。

注意“重新安装”的意思是“使指针或智能指针指向不同的对象。”</p>

我不明白为什么当 reseat 意味着“使指针或智能指针指向不同的对象”时我们应该通过引用传递。</p>

当函数的目的是重新设置/更改指针指向的基础对象时,我们不是以这种方式从调用者那里窃取所有权,因此应该传递unique_ptr按值,从而移动它并转移所有权吗?

有没有一个例子可以解释为什么unique_ptr推荐通过引用传递?

标签: c++c++11cpp-core-guidelines

解决方案


当函数的目的是重置/更改指针指向的底层对象时,我们不是这样从调用者那里窃取所有权吗

不,当我们“重新定位”一个指针时,或者当我们改变指向的对象时,我们都没有获得指针的所有权,即我们没有转移所有权。

是否有一个示例可以解释为什么建议通过引用传递 unique_ptr ?

下面是一个“重置”唯一指针的函数示例:

void reseat(std::unique_ptr<widget>& ptr) {
    ptr = std::make_unique<widget>();
}

如果您尝试使用对 const 的引用,则根本无法编译。如果您尝试使用非引用参数,则参数指针将不会被修改,因此行为不会如预期那样。调用者将被迫移动他们的指针,使其始终为空。

您可以修改示例以使用指向唯一指针的指针,但建议使用引用,因为不可能错误地传递 null。引用包装器也可以工作,但它会不必要地复杂。

如果我们让它指向其他地方,它之前指向的对象会发生什么?

如果一个唯一的指针指向非空的东西,那么让它指向别处将导致先前指向的对象被删除。

在这种情况下我们不是在泄漏内存吗?

不。


请注意,示例很简单,以便于理解。通常我不建议编写这样的函数,而是考虑编写一个返回新唯一指针的函数,并让调用者自己“重新定位”指针。但这取决于细节。


推荐阅读