将unique_ptr传递给函数

我试图“现代化”一些现有的代码。

  • 我有一个类,目前有一个成员variables“设备*设备_”。
  • 它使用new在某些初始化代码中创build一个实例,并在结构中有一个“delete device_”。
  • 这个类的成员函数调用许多其他的以Device *为参数的函数。

这很好,但为了“代码化”我想我应该改变variables定义为"std::unique_ptr<Device> device_"并删除显式调用删除,这使得代码更安全,通常更好。

我的问题是这个 –

  • 那么我应该如何将设备 _variables传递给所有需要它作为参数的函数呢?

我可以调用.get来获取每个函数调用中的原始指针。 但是,这似乎是丑陋的,浪费了一些使用unique_ptr的原因。

或者我可以改变每一个函数,而不是采取“Device *”types的参数,现在它需要一个types为“std :: unique_ptr&”的参数。 哪(对我)有点混淆函数原型,并使他们难以阅读。

这个最好的做法是什么? 我错过了其他select吗?

现代 C ++风格中,有两个关键概念:

  • 所有权
  • 婚姻无效

所有权是关于某个对象/资源的所有者(在这种情况下是Device一个实例)。 各种std::unique_ptrboost::scoped_ptrstd::shared_ptr都是关于所有权的。

Nullity更简单:它只是表示一个给定的对象是否可以是null,并不关心其他任何东西,当然不是关于所有权!


如果你的目标是实现一个PIMPL,你可能需要一个带有深层副本语义的智能指针,这样你就可以把你的类的实现移到unique_ptr (一般情况)。

这清楚地表明,你的class级是唯一负责这段记忆的人,而且整洁地处理记忆本来可能泄漏的各种方式。


另一方面,资源的大多数用户不关心它的所有权。

只要一个函数不保存一个对象的引用(将其存储在一个映射或其他东西),那么重要的是对象的生命周期超过函数调用的持续时间。

因此,select如何传递参数取决于其可能的Nullity

  • 永不为空? 通过参考
  • 可能为空? 传递一个指针 ,一个简单的裸指针或一个类指针(例如一个陷阱为空)

这真的取决于。 如果一个函数必须拥有unique_ptr的所有权,那么它的签名应该采用unique_ptr<Device> bv ,调用者应该std::move指针。 如果所有权不是问题,那么我会保留原始指针签名,并使用get()传递指针unique_ptr。 如果相关function不接pipe所有权,这并不难看。

我会使用std::unique_ptr const& 。 使用非const引用将使被调用的函数可以重置您的指针。
我认为这是一个很好的方式来expression你的被调用的函数可以使用指针,但没有别的。
所以对我来说这将使界面更容易阅读。 我知道,我不必用指针传给我。

在这种情况下,最好的做法可能不是使用std::unique_ptr ,尽pipe这取决于。 (你通常不应该在一个类中有一个以上的指向dynamic分配对象的原始指针,尽pipe这也取决于你)在这种情况下,你不想做的一件事是传递std::unique_ptr (和你已经注意到了, std::unique_ptr<> const&有点笨拙和混淆)。 如果这是对象中唯一dynamic分配的指针,那么我只是坚持原始指针,并在析构函数中delete 。 如果有几个这样的指针,我会考虑把它们分别放到一个单独的基类(它们仍然是原始指针)。

这对你来说可能是不可行的,但是用const unique_ptr<Device>&replaceDevice*的每一次出现const unique_ptr<Device>&是一个好的开始。

你显然不能复制unique_ptr ,你不想移动它。 通过对unique_ptr的引用replace,可以使现有函数的主体继续工作。

现在有一个陷阱,你必须通过const &来阻止被调用者执行unique_ptr.reset()或者unique_ptr().release() 。 请注意,这仍然传递一个可修改的指针到设备。 有了这个解决scheme,你没有简单的方法将指针或引用传递给const Device