【cmu15445c++入门】(9)C++ 智能指针shared_ptr

一、智能指针shared_ptr

std::shared_ptr 是一种智能指针,它通过指针保留对象的共享所有权。这意味着多个共享指针可以拥有同一个对象,并且可以复制共享指针。

二、代码 


// In this file, we'll talk about std::shared_ptr, which is a C++ smart pointer.
// See the intro of unique_ptr.cpp for an introduction on smart pointers.
// std::shared_ptr is a type of smart pointer that retains shared ownership of
// an object through a pointer. This means that multiple shared pointers can
// own the same object, and shared pointers can be copied.

//std::shared_ptr 是一种智能指针,它通过指针保留对象的共享所有权。
//这意味着多个共享指针可以拥有同一个对象,并且可以复制共享指针。

// Includes std::cout (printing) for demo purposes.
#include <iostream>
// Includes std::shared_ptr functionality.
#include <memory>
// Includes the utility header for std::move.
#include <utility>

// Basic point class. (Will use later)
class Point {
public:
  Point() : x_(0), y_(0) {}
  Point(int x, int y) : x_(x), y_(y) {}
  inline int GetX() { return x_; }
  inline int GetY() { return y_; }
  inline void SetX(int x) { x_ = x; }
  inline void SetY(int y) { y_ = y; }

private:
  int x_;
  int y_;
};

// Function that modifies a Point object inside a shared pointer
// by passing the shared pointer argument as a reference.
void modify_ptr_via_ref(std::shared_ptr<Point> &point) { point->SetX(15); }

// Function that modifies a Point object inside a shared pointer
// by passing the shared pointer argument as a rvalue reference.
void modify_ptr_via_rvalue_ref(std::shared_ptr<Point> &&point) {
  point->SetY(645);
}

void copy_shared_ptr_in_function(std::shared_ptr<Point> point) {
  std::cout << "Use count of shared pointer is " << point.use_count()
            << std::endl;
}

int main() {
  // This is how to initialize an empty shared pointer of type
  // 下面是几种智能指针的初始化方法
  // std::shared_ptr<Point>.
  std::shared_ptr<Point> s1;
  // This is how to initialize a shared pointer with the default constructor.
  std::shared_ptr<Point> s2 = std::make_shared<Point>();
  // This is how to initialize a shared pointer with a custom constructor.
  std::shared_ptr<Point> s3 = std::make_shared<Point>(2, 3);

  // The specific syntax for checking whether a smart pointer is empty is
  // covered in unique_ptr.cpp (line 56). Note that s1 is empty, while s2 and
  // s3 are not empty.
  std::cout << "Pointer s1 is " << (s1 ? "not empty" : "empty") << std::endl;
  std::cout << "Pointer s2 is " << (s2 ? "not empty" : "empty") << std::endl;
  std::cout << "Pointer s3 is " << (s3 ? "not empty" : "empty") << std::endl;

  // It is possible to copy shared pointers via their copy assignment and copy
  // constructor operators. Using these copy operators will increase the
  // reference count of the overall object. Also, std::shared_ptr comes with
  // a method called use_count which keeps track of the number of objects
  // currently interacting with the same internal data as the current shared
  // pointer instance.
  // 可以通过共享指针的复制赋值和复制构造函数运算符来复制共享指针。
  // 使用这些复制运算符将增加整个对象的引用计数。
  // 此外,std::shared_ptr 还附带了一个名为 use_count 的方法,该方法跟踪当前与当前共享指针实例相同的内部数据交互的对象数量。

  // First, the number of references to pointer s3 is obtained. This should be
  // 1 because s3 is the only object instance using the data in s3.
  // 初始时候,s3的引用计数为1
  std::cout
      << "Number of shared pointer object instances using the data in s3: "
      << s3.use_count() << std::endl;

  // Then, s4 is copy-constructed from s3.
  // This is copy-construction because it is the first time s4 appears.
  // 接着,s4也拷贝自s3,s3的引用计数为2。因为s3和s4都指向s3的数据
  std::shared_ptr<Point> s4 = s3;

  // Now, the number of references to pointer s3's data should be 2, since both
  // s4 and s3 have access to s3's data.
  std::cout << "Number of shared pointer object instances using the data in s3 "
               "after one copy: "
            << s3.use_count() << std::endl;

  // Then, s5 is copy-constructed from s4.
  
  std::shared_ptr<Point> s5(s4);

  // Now, the number of references to pointer s3's data should be 3, since s5,
  // s4, and s3 have access to s3's data.
  // 接着,s5拷贝自s4,s3的引用计数为3。因为s3\s4\s5都指向s3的数据
  std::cout << "Number of shared pointer object instances using the data in s3 "
               "after two copies: "
            << s3.use_count() << std::endl;

  // Modifying s3's data should also change the data in s4 and s5, since they
  // refer to the same object instance.
  // 修改s3的数据。s4\s5也会跟着一块变化
  s3->SetX(445);

  std::cout << "Printing x in s3: " << s3->GetX() << std::endl;
  std::cout << "Printing x in s4: " << s4->GetX() << std::endl;
  std::cout << "Printing x in s5: " << s5->GetX() << std::endl;

  // It is also possible to transfer ownership of a std::shared_ptr by moving
  // it. Note that the pointer is empty after the move has occurred.
  // 也可以通过move函数,来转让它的所有权。请注意,move发生后指针为空。
  std::shared_ptr<Point> s6 = std::move(s5);

  // Note that s5 is now empty, s6 refers to the same data as s3 and s4, and
  // there are still 3 shared pointer instances with access to the same Point
  // instance data, not 4.
  // move之后,s3\s4\s6都指向s3的数据,s5为空
  std::cout << "Pointer s5 is " << (s5 ? "not empty" : "empty") << std::endl;
  std::cout << "Number of shared pointer object instances using the data in s3 "
               "after two copies and a move: "
            << s3.use_count() << std::endl;

  // Similar to unique pointers, shared pointers can also be passed by reference
  // and rvalue reference. See unique_ptr.cpp (line 89) for a information on
  // passing unique pointers by reference. See references.cpp for more
  // information on references. See move_semantics.cpp for more information on
  // rvalue references. Here, we present code below that calls functions that
  // modify s2 by passing a shared pointer as a reference and as a rvalue
  // reference.
  // 与unique_ptr指针类似,shared_ptr也可以通过引用和右值引用传递。
  // 有关参考文献的更多信息,请参阅references.cpp。有关右值引用的更多信息,请参阅move_semantics.cpp。
  // 在这里,我们在下面介绍代码,这些代码通过传递shared_ptr作为引用和右值引用来调用修改 s2 的函数。
  
  modify_ptr_via_ref(s2);
  modify_ptr_via_rvalue_ref(std::move(s2));

  // After running this code, s2 should have x = 15 and y = 645.
  std::cout << "Pointer s2 has x=" << s2->GetX() << " and y=" << s2->GetY()
            << std::endl;

  // Unlike unique pointers, shared pointers can also be passed by value. In
  // this case, the function contains its own copy of a shared pointer, which
  // destroys itself after the function is finished. In this example, before s2
  // is passed to the function by value, its use count is 1. While it is in the
  // function, its use count is 2, because there is another copy of s2's data in
  // the shared pointer instance in the function. After the function goes out of
  // scope, this object in the function is destroyed, and the use count returns
  // to 1.
  // 与unique_ptr不同,shared_ptr也可以按值传递。在这种情况下,函数包含自己的共享指针副本,该指针在函数完成后会自行销毁。
  // 在此示例中,在 s2 按值传递给函数之前,其使用计数为 1。
  // 当它在函数中时,它的使用计数为 2,因为函数的共享指针实例中还有一个s2数据副本。
  // 函数结束后,函数中的此对象将被销毁,使用计数返回为 1。


  std::cout
      << "Number of shared pointer object instances using the data in s2: "
      << s2.use_count() << std::endl;
  copy_shared_ptr_in_function(s2);
  std::cout << "Number of shared pointer object instances using the data in s2 "
               "after calling copy_shared_ptr_in_function: "
            << s2.use_count() << std::endl;

  return 0;
}

三、运行 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

康雨城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值