Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将共享的ptr作为参数传递给可变对象?_C++_Boost_C++11_Smart Pointers - Fatal编程技术网

C++ 如何将共享的ptr作为参数传递给可变对象?

C++ 如何将共享的ptr作为参数传递给可变对象?,c++,boost,c++11,smart-pointers,C++,Boost,C++11,Smart Pointers,我想通过智能指针引用将对象传递给函数。函数可以更改被引用对象的值,但不能更改引用本身。有两种明显的方法来处理这个问题 第一种通过值传递共享_ptr的方法——它是引用,因此本身不需要通过引用传递。这方面的明显问题是引用的复制,这意味着一些引用计数开销 void foo (shared_ptr<bar> p) void foo(共享) 第二种方法是通过const引用传递共享的_ptr——避免复制共享的_ptr实例,但这意味着对引用对象的访问需要两层而不是一层去引用 void foo

我想通过智能指针引用将对象传递给函数。函数可以更改被引用对象的值,但不能更改引用本身。有两种明显的方法来处理这个问题

第一种通过值传递共享_ptr的方法——它是引用,因此本身不需要通过引用传递。这方面的明显问题是引用的复制,这意味着一些引用计数开销

void foo (shared_ptr<bar> p)
void foo(共享)
第二种方法是通过const引用传递共享的_ptr——避免复制共享的_ptr实例,但这意味着对引用对象的访问需要两层而不是一层去引用

void foo (const shared_ptr<bar> &p)
void foo(const shared\u ptr&p)
在实践中,这些理论上的开销通常是微不足道的。这对我来说意味着,我应该遵循一些标准惯例,而不是为每个个案选择一种或另一种方法。这就引出了一个问题

是否有一个标准惯例,我通常应该选择哪种方法?如果是,传统的选择是什么


<强>编辑< /强> -值得一提的是,考虑PASS CONST COST引用情况的一个原因是因为存在一个预先存在的约定,即大多数类/结构实例通过const引用而不是值传递,并且<代码> SydDypTr>/Cuth>是一个类。当然,它不是一个重量级的类(复制的成本很低),因此旧的约定背后的原因可能不适用。

总是通过值传递
共享。如果传递引用,您可能会遇到这样的问题:对
共享\u ptr
管理的对象的函数的调用可能会将其重置,现在您有了一个悬空指针。如果按值传递,则可以确保对象在当前函数调用后仍然有效

有关更多信息,请参阅


例如:

#include <memory>
#include <iostream>

std::shared_ptr<int> ptr(new int(42));

void foo(){
  ptr.reset();
}

void bar(std::shared_ptr<int> const& p){
  foo();
  std::cout << *p;
}

int main(){
  bar(ptr);
}
#包括
#包括
std::共享ptr(新int(42));
void foo(){
ptr.reset();
}
空栏(标准::共享\u ptr const&p){
foo();

std::cout一个@Xeo所说的例子:

void foo(shared_ptr<bar> &p)
{
    p.reset(); // ref_count == 0; memory is freed.
}

shared_ptr<bar> p(new bar); // ref_count == 1
foo(p);
void foo(共享\u ptr&p)
{
p、 reset();//ref_count==0;内存已释放。
}
共享_ptr p(新条);//ref_count==1
富(p),;

如果操作对象的函数包含在智能指针中,则该对象不应该相关。它应该接受一个
T&
。一些人认为操作值的自由函数风格不好。通过引用const获取对象并返回一个新的值可以更干净。

我一直在传递const&基于这样一个想法,即在调用堆栈的某个位置,应该有人持有共享的ptr副本,因此它的生命对于我的整个执行是有保证的

如果您在另一个线程上执行,则需要一个副本—因此,任何存储共享的_ptr(不仅仅在其方法期间使用它)的人都需要存储一个副本,而不是引用


而且,既然我已经写好了,我将去读一读为什么人们似乎支持相反的心态。

我在发布之前错过了一个可能的副本——但这可能更具体地针对某个特定的要求,而不是一般的惯例。·无论如何,可能存在微观效率低下的问题,所以要明确。按价值传递。这就是这就是你对一个原始指针所做的,也就是说,这是既定的惯例。任何其他的事情都会让读者想知道为什么。这可能是沟通错误,不清楚。干杯&hth.,@Alf-我一直在思考你所说的。一个回应是我的编辑,但这并不意味着我不同意。原始引用也不能通过引用传递(虽然一个原始指针可以),所以我不确定“约定”是正确的词,但是强制的练习当然是常规的。我认为你有一点,但是我仍然有疑问——C++中,通过const引用传递结构/类实例是如此普遍(出于效率的原因,但也作为惯例)。,这样做是否意味着意图?也许可以,但可能不是以任何明确/明确的方式。@AlfP.Steinbach“无论如何都可能存在微观效率低下问题”你测量过这些吗?@curiousguy:我不可能测量OP的代码。一种可能有固定的设置开销,另一种可能有每次访问的开销。因此,行为取决于这些可能性中的哪一种(如果有)显示它们自己,以及每个函数调用的访问量。干杯,对指针管理的对象的函数的调用如何重置指针,或者对指针有任何影响?或者我读得不对吗?@Steve:不能通过此引用更改指针并不意味着它不能被更改外部愤怒。@xeo:我同意“始终传递”值。但是,当形式参数引用常量时,则不会造成任何伤害(也就是说,除了ref-to-const参数通常可能出现的别名之外,我从未遇到过这种情况,这同样适用于ref-to-const形式参数的任何使用)。这只是一个可能的微低效。干杯,@Xeo-同意,但这是一个标准的pass-by-const引用问题,通常不会让任何人担心。如果多线程是一个问题,这是您的最小问题。如果您保存该引用的副本,假设这意味着复制共享的\u ptr实例,您应该可以。否则,问题可能会发生't rease-在您使用引用时,函数外部的任何内容都不能更改引用,因为函数外部的任何内容都不能执行,直到函数退出并且参数仍然死亡。@Xeo:下面是一个人为的示例,显示您不应该通过引用传递布尔值。我认为您缺少了一个
p.reset()
或类似的东西?
共享\u ptr