首页 > 解决方案 > 何时应将 shared_ptr 作为原始指针传递?

问题描述

我正在阅读有关应如何传递共享指针的信息。我遇到了这个链接,其中指出

指南:使用非常量 shared_ptr& 参数仅用于修改 shared_ptr。仅当您不确定是否会复制并共享所有权时,才使用 const shared_ptr& 作为参数;否则使用 widget* 代替(或者如果不可为空,则使用 widget&)。

我对上述陈述有两个问题

问题一:

它指出

.. 否则使用 widget* 代替(或者如果不可为空,则使用 widget&)。

这是否意味着如果我们有这样的东西

std::shared_ptr<foo> f = std::make_shared<foo>();

我们需要将它传递给不同的方法。该方法应该具有类似的签名

void doSomething(foo* ptr); //assuming its nullable

所以使用它将是

doSomething(f.get());

这个对吗 ?如果是这样,那么这不会很危险吗?如果 f 的引用计数变为 0 那么 ptr 基本上是无效的?在哪种情况下,我想创建一个接收原始指针的方法?为什么我要像这样传递一个智能指针?

问题2 在这里修改是什么意思?如何修改共享指针?

仅使用非常量 shared_ptr& 参数来修改 shared_ptr

标签: c++11shared-ptrsmart-pointers

解决方案


所有这些都是对简化代码和可读性的考虑,其中函数签名被用作函数用途的线索。

如果一个函数在访问它时需要指向对象的指针的共享状态,那么将它作为共享指针传递是没有实际意义的,除非函数是为了获取它的所有权。即foo()带有签名的函数

void  foo( std::shared_ptr<Object> p);  // it shares ownership

将控制 Object 实例,因为参数p是.foo()

具有非常量引用签名的函数会质疑它们的实际含义:

void  foo( std::shared_ptr<Object>& p);  // new storage may be assigned

他们可以更改共享指针拥有的对象,也可以通过调用其方法p来更改-修改-指针本身。reset()该指南提议将其用于后者,因为使用共享状态来取消引用指针会产生成本。前一个任务可以通过原始参考轻松完成:

void  foo( Object& p);  // object may change but occupies same storage

.get()如果can的结果是原始指针是有意义的nullptr,否则受控对象最好通过引用传递。

最后,常量引用允许创建另一个共享或弱指针或更改对象,但不允许修改原始指针。这个签名表明 foo()可以做前者。

void  foo(const shared_ptr<Object>& p); // p cannot be changed but may be shared

推荐阅读