C++ 智能指针

在C++ 11中添加了几个智能指针类,用于管理动态分配的内存。通过使用这些容器类,而不是原始指针,不再需要手动删除使用new关键字创建的对象。这有助于防止内存泄漏,从而简化了编码。

唯一指针

我们要关注的第一个智能指针是唯一指针(std::unique_ptr),它仅充当原始指针的容器。 它替换了另一个不推荐使用的智能指针auto_ptr,该指针已在C++ 17中删除。考虑以下有关如何使用唯一指针的示例。

#include <memory> // include smart pointers
#include <iostream>
using namespace std;
struct Foo
{
  int val;
  Foo() { cout << "1"; }
 ~Foo() { cout << "3"; }
};
int main()
{
  unique_ptr<Foo> p(new Foo()); // "1"
  p->val = 2;
  cout << p->val; // "2"
} // "3"

此智能指针创建、使用时此段代码输出“123”,以及超出定义域后自动销毁。请注意,智能指针不是通过赋值创建的,而是通过将原始指针传递给其构造函数来创建的。但是,一旦创建,智能指针就将用作常规指针,在这种情况下,使用箭头运算符(->)可以解引用指针并在单个操作中访问对象的成员。

顾名思义,唯一指针对其指向的对象具有独占所有权,因此无法复制。但是,它可以使用std::move函数将所有权转移到另一个唯一的指针。完成这样的传输后,原始指针将设置为nullptr。

unique_ptr<Foo> u1(new Foo());
unique_ptr<Foo> u2 = u1; // compile-time error
unique_ptr<Foo> u3 = move(u1); // transfers ownership

共享指针

如果需要动态分配对象的共享所有权,则存在共享指针(std::shared_ptr)。与唯一指针不同,共享指针可以复制。在拥有该对象的最后剩余共享指针因超出定义域或手动设置为nullptr导致该共享指针被销毁之前,不会释放对象的内存。

shared_ptr<Foo> s1(new Foo());
shared_ptr<Foo> s2 = s1; // extends ownership
s1 = nullptr; // reset pointer
s2 = nullptr; // reset last pointer and delete memory

从C++ 14开始,在大多数情况下不建议使用new关键字。而是在分配动态内存时建议使用std::make_unique和std::make_shared函数。

unique_ptr<Foo> u = make_unique<Foo>();
shared_ptr<Foo> s = make_shared<Foo>();

弱共享指针

可以从共享指针创建弱共享指针(std::weak_ptr)。与共享指针不同,弱共享指针是没有所有权的,这意味着当所有共享指针超出作用域时,该对象将被清除,而与任何弱共享指针无关。为了访问引用的对象,必须首先使用lock方法将弱共享指针转换为共享指针。以下例子来具体说明:

#include <memory>
#include <iostream>
using namespace std;
void observe(weak_ptr<int> weak)
{
  shared_ptr<int> s = weak.lock();
  if (s != nullptr) {
    cout << "Pointer is " << *s << endl;
  }
  else {
    cout << "Pointer has expired" << endl;
  }
}
int main()
{
  shared_ptr<int> s = make_shared<int>(5);
  weak_ptr<int> w = s; // copy pointer without ownership
  observe(w); // "Pointer is 5"
  s = nullptr; // delete managed object
  observe(w); // "Pointer has expired"
}

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据