一、智能指针
智能指针是一种数据结构,用于没有内置内存管理的语言(例如 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;
}