简体   繁体   English

调用`shared_ptr.get()`vs复制初始化,有什么区别?

[英]Calling `shared_ptr.get()` vs copy-initialization, what's the difference?

first version print use_count = 2; 第一版print use_count = 2;

shared_ptr<int> s{make_shared<int>(15)};
  auto b = s;
  cout<<s.use_count()<<endl;
  auto c = s.get();
  cout<<s.use_count()<<endl;
  cout<<*c<<endl;  

second version use_count = 3; 第二版本use_count = 3;

shared_ptr<int> s{make_shared<int>(15)};
  auto b = s;
  cout<<s.use_count()<<endl;
  auto c = s;
  cout<<s.use_count()<<endl;
  cout<<*c<<endl;  

Question: 题:

  • Why is the behavior different between the two versions? 为什么两个版本之间的行为不同?

Introduction 介绍

Every time you make a copy of a shared_ptr the use-count is increased since you then have an additional handle to the underlying resource being tracked. 每次您复制shared_ptr副本时, 使用计数都会增加,因为这样您就可以对正在跟踪的基础资源进行额外的处理。

In order to obtain the value of the underlying pointer, shared_ptr has a member-function named get . 为了获得基础指针的值, shared_ptr有一个名为get的成员函数。 This function will return the address of the tracked resource, it will not create an additional shared_ptr tracking the same pointer. 此函数将返回被跟踪资源的地址,它将不会创建跟踪同一指针的其他shared_ptr


Potential dangers 潜在危险

In your first snippet you effectively have 2 instances of shared_ptr that refers to the same resource, but in the latter you have three. 在您的第一个代码段中,您实际上有2个shared_ptr实例,它们引用相同的资源,但是在后者中,您有3个实例。

The difference being; 区别在于;

  • auto a = s will create a copy of s , and the type of a is that of s (a shared_ptr ) auto a = s将创建的副本s ,和类型a是, s (一个shared_ptr)
  • auto b = s.get () will initialize b with the address of the tracked resource managed by s , hence it will be a raw-pointer . auto b = s.get ()将使用s管理的跟踪资源的地址来初始化b ,因此它将是原始指针

If you don't know exactly what you are doing, calling .get () might be dangerous, as can be seen in the following snippet. 如果您不确定自己在做什么,则调用.get ()可能很危险,如下面的代码片段所示。

int * ptr = nullptr;

{
  std::shared_ptr<int> sp { make_shared<int> (15) };
  ptr = sp.get ();
}

std::cout << *ptr << std::endl; // (A), dangling pointer

Inside our nested scope we create a shared_ptr named sp , and we ask it to keep track of an int with dynamic storage duration created from our call to make_shared . 在我们的嵌套范围内,我们创建一个名为spshared_ptr ,并要求它跟踪从对make_shared的调用创建的具有动态存储持续时间int

We obtain the address of this int by calling sp.get () , and assign it to ptr . 我们通过调用sp.get ()获得此int的地址,并将其分配给ptr

When the scope of sp ends, sp will release the resource managed since there's no more *shared_ptr*s that refers to it. sp的作用域结束时,由于不再有引用它的* shared_ptr * s, sp将释放所管理的资源。

By trying to print the value of *ptr we are invoking undefined behavior in ( A ) since the value isn't available, it was destroyed with the destruction of sp . 通过尝试打印*ptr的值,我们在( A )中调用未定义的行为 ,因为该值不可用,它被破坏了sp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 可以由多个线程调用shared_ptr.get(),而另一个线程锁定并调用shared_ptr.swap()吗? - Can shared_ptr.get() be called by multiple threads while another thread locks and calls shared_ptr.swap()? 复制列表初始化和传统复制初始化有什么区别? - Any difference between copy-list-initialization and traditional copy-initialization? 它是直接初始化还是复制初始化? - Is it direct-initialization or copy-initialization? 复制构造函数是否不用于复制初始化或优化? - Copy constructor is not called for copy-initialization or optimized? “复制初始化上下文中的默认初始化”在C ++中意味着什么? - What does 'default-initialization in copy-initialization context' mean in C++? C++ class 类型复制初始化 - C++ class type copy-initialization 引用类型复制初始化的问题 - Issues about the copy-initialization of reference type 在c ++中使用隐式转换进行复制初始化 - Copy-initialization with implicit conversion in c++ 与显式初始化相比,了解C ++中的复制初始化 - Understanding copy-initialization in C++, compared to explicit initialization 在复制初始化中,对复制构造函数的调用是显式还是隐式的? - In copy-initialization, is the call to the copy constructor explicit or implicit?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM