【cmu15445c++入门】(8)C++ 智能指针unique_ptr

一、智能指针

智能指针是一种数据结构,用于没有内置内存管理的语言(例如 C++)中的内存管理(有时还有其他功能)。内置内存管理的语言的指的是具有垃圾回收功能的语言,如Java、Python。

现代C++标准库的两个智能指针(以及您将在类中使用的智能指针)是 std::unique_ptr 和 std::shared_ptr。

std::unique_ptr 和 std::shared_ptr 都自动处理内存分配和释放,并在幕后包含原始指针。换句话说,它们是原始指针的包装类。 在这个文件中,我们将讨论 std::unique_ptr。std::unique_ptr 是一种智能指针,保留对象的唯一所有权。

这意味着 std::unique_ptr 的两个实例不能管理同一对象。

二、代码示例

cpp 复制代码
// A smart pointer is a type of data structure used for memory management (and
// sometimes other features) in languages that don't have memory management
// built in (e.g C++) An example of a language that has memory management built
// in is any language with garbage collection, like Java or Python. Two of the
// modern C++ standard library's smart pointers (and the ones that you will use
// in class) are std::unique_ptr and std::shared_ptr. Both std::unique_ptr and
// std::shared_ptr handle memory allocation and deallocation automatically, and
// contain raw pointers under the hood. In other words, they are wrapper classes
// over raw pointers. In this file, we'll talk about std::unique_ptr.
// std::unique_ptr is a type of smart pointer that retains sole ownership of an
// object This means that no two instances of std::unique_ptr can manage the
// same object.
//智能指针是一种数据结构,用于没有内置内存管理的语言(例如 C++)中的内存管理(有时还有其他功能)。
//内置内存管理的语言的指的是具有垃圾回收功能的语言,如Java、Python。
//现代C++标准库的两个智能指针(以及您将在类中使用的智能指针)是 std::unique_ptr 和 std::shared_ptr。 
//std::unique_ptr 和 std::shared_ptr 都自动处理内存分配和释放,并在幕后包含原始指针。 
//换句话说,它们是原始指针的包装类。 在这个文件中,我们将讨论 std::unique_ptr。 
//std::unique_ptr 是一种智能指针,保留对象的唯一所有权。
//这意味着 std::unique_ptr 的两个实例不能管理同一对象。

// Includes std::cout (printing) for demo purposes.
#include <iostream>
// Includes std::unique_ptr functionality.
#include <memory>
// String library for printing help for demo purposes.
#include <string>
// Including 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 takes in a unique pointer reference and changes its x value to
// 445.
void SetXTo445(std::unique_ptr<Point> &ptr) { ptr->SetX(445); }

int main() {
  // This is how to initialize an empty unique pointer of type
  // std::unique_ptr<Point>.
  std::unique_ptr<Point> u1;
  // This is how to initialize a unique pointer with the default constructor.
  std::unique_ptr<Point> u2 = std::make_unique<Point>();
  // This is how to initialize a unique pointer with a custom constructor.
  std::unique_ptr<Point> u3 = std::make_unique<Point>(2, 3);

  // Here, for std::unique_ptr instance u, we use the statement (u ? "not empty"
  // : "empty") to determine if the pointer u contains managed data. The main
  // gist of this is that the std::unique_ptr class has a conversion function on
  // its objects to a boolean type, and so this function is called whenever we
  // treat the std::unique_ptr as a boolean. For instance, this can be used in
  // the following example.

  // 通过判断u是否为空,决定u是否包含包含托管数据。 
  // 此处的要领是,unique_ptr具有转换函数,能够把对象转为bool型
  // 所以,每当我们将 std::unique_ptr 视为布尔值时,就会调用此函数。
  if (u1) {
    // This won't print because u1 is empty.
    std::cout << "u1's value of x is " << u1->GetX() << std::endl;
  }

  if (u2) {
    // This will print because u2 is not empty, and contains a managed Point
    // instance.
    std::cout << "u2's value of x is " << u2->GetX() << std::endl;
  }

  // Note that u1 is empty and u2 and u3 are not empty, since they were
  // initialized with a Point instance.
  std::cout << "Pointer u1 is " << (u1 ? "not empty" : "empty") << std::endl;
  std::cout << "Pointer u2 is " << (u2 ? "not empty" : "empty") << std::endl;
  std::cout << "Pointer u3 is " << (u3 ? "not empty" : "empty") << std::endl;

  // Since instances of std::unique_ptr can have only one owner, it has no copy
  // constructor. Therefore, this code won't compile. Uncomment it to try!
  // 因为unique_ptr只能有一个owener,没有copy类型的构造方法。所以,下面的代码编译不通过
  // std::unique_ptr<Point> u4 = u3;


  // However, it's possible to transfer ownership of unique pointers via------通过move函数可以
  // std::move.
  std::unique_ptr<Point> u4 = std::move(u3);

  // Note that because u3 is an lvalue, it no longer contains any managed
  // object. It is an empty unique pointer. Let's retest for emptyness.
  // move之后,u3已经不包含任何对象。
  std::cout << "Pointer u3 is " << (u3 ? "not empty" : "empty") << std::endl;
  std::cout << "Pointer u4 is " << (u4 ? "not empty" : "empty") << std::endl;

  // Lastly, let's talk about how to pass std::unique_ptr instances as arguments
  // to functions. Mainly, you should pass it as a reference so that the
  // ownership doesn't change. You can see this as an example in the function
  // SetXTo445 (line 44 in this file).
  SetXTo445(u4);

  // Now, let's print the x value of u4 to confirm that the change occured, but
  // the ownership of the Point instance has been retained to u4.
  std::cout << "Pointer u4's x value is " << u4->GetX() << std::endl;

  return 0;
}

三、运行结果

相关推荐
蠢蠢的打码15 分钟前
8622 哈希查找
数据结构·c++·算法·链表·图论
无职转生真好看19 分钟前
LeetCode236题:二叉树的最近公共祖先
c++
重生之我在20年代敲代码2 小时前
C语言-动态内存分配讲解
c语言·开发语言·数据结构·c++·经验分享·笔记
sun0077002 小时前
cmake如何在编译时区分-std=c++17和-std=gnu++17?检查宏
开发语言·c++·算法
被二进制支配的打工人3 小时前
C++ string的基本运用详细解剖
开发语言·数据结构·c++·string
Another_Shi7 小时前
数据结构:详解搜索二叉树
数据结构·c++
燚泽7 小时前
7-地图和导航
c++·python·测试工具·自动驾驶
熙曦Sakura8 小时前
【C/C++】错题记录(一)
java·c语言·c++
2301_775602388 小时前
C++11 多线程编程-小白零基础到手撕线程池
开发语言·c++
码农豆豆9 小时前
11.C++程序中的常用函数
开发语言·c++·算法