ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

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

【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 的两个实例不能管理同一对象。

 二、代码示例

// 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;
}

三、运行结果

返回列表