📜  C++中智能指针及其类型的介绍(1)

📅  最后修改于: 2023-12-03 14:59:50.081000             🧑  作者: Mango

C++中智能指针及其类型的介绍

在C++中,使用普通裸指针存在风险,因为裸指针存在空悬指针、重复释放等问题。同时,在面对异常情况时,手动释放内存也容易被遗漏。因此,C++引入了智能指针的概念,用以管理动态内存的生命周期,提高了代码的安全性和可靠性。

智能指针的定义

智能指针是一种类似于指针的对象,它在指针的基础上增加了一些智能化功能,如自动管理内存。智能指针会在其所指向的对象不再被引用时,自动析构并释放其占用的空间,从而避免内存泄漏。

在C++中,STL库提供了三种不同的智能指针类型:unique_ptr、shared_ptr和weak_ptr。

unique_ptr

unique_ptr是一种独占式智能指针,即它所指向的对象只能有一个unique_ptr指针拥有。当unique_ptr失去对所指对象的所有权时,它会自动析构并释放内存空间。

#include <memory>

std::unique_ptr<int> p1(new int(123));
std::unique_ptr<int> p2 = std::make_unique<int>(456);

上述代码中,p1和p2都是unique_ptr指针,分别指向动态分配的int类型数据。p1和p2都是独占式智能指针,因此它们拥有各自指向的对象。

可以通过std::move函数将p1的所有权转移到p3:

std::unique_ptr<int> p3;
p3 = std::move(p1);

此时,p1不再拥有指向的对象,因为其所有权已经转移到了p3中。p1会自动析构指向的对象,并释放空间。

shared_ptr

shared_ptr是一种共享式智能指针,多个shared_ptr可以指向同一个对象。shared_ptr内部维护了一个引用计数器,计算有多少个shared_ptr指针对象共享同一份资源。只有当所有的shared_ptr对象都失去了指向该对象的所有权时,该对象才会自动析构并释放空间。

#include <memory>

std::shared_ptr<int> p1(new int(123));
std::shared_ptr<int> p2 = p1;

上述代码中,p1和p2指向同一个动态分配的int类型数据。因为p1和p2都是shared_ptr指针,所以它们共享同一份资源。此时,int类型数据的引用计数为2。

可以通过reset函数将p2的所有权移交给p3:

std::shared_ptr<int> p3;
p3.reset(new int(456));
p3 = p2;

此时,p1、p2和p3都指向同一份int类型数据,其引用计数为3。只有当p1、p2和p3都失去对该int类型数据的指向时,该数据才会自动析构并释放空间。

weak_ptr

weak_ptr也是一种共享式智能指针,它指向由shared_ptr管理的对象,但是并不拥有该对象的所有权。weak_ptr只是用于协助shared_ptr完成管理任务,可以检查shared_ptr可能已经被销毁,并帮助避免空悬指针。

#include <memory>

std::shared_ptr<int> sp(new int(123));
std::weak_ptr<int> wp(sp);
if (auto p = wp.lock()) {
    // shared_ptr对象尚未失效,可以安全使用p指针
}

上述代码中,wp是一个weak_ptr指针,指向由sp所管理的动态分配的int类型数据。可以通过lock函数获取一个shared_ptr对象来管理该数据。如果shared_ptr对象已经失效,lock函数会返回一个空的shared_ptr指针。

总结

智能指针是一个强大的C++编程工具,它可以自动管理内存,提高代码的安全性和可靠性。unique_ptr适用于独占式所有权,shared_ptr适用于共享式所有权,而weak_ptr则适用于辅助shared_ptr进行内存管理。在实际编程中,选择适当的智能指针类型可以有效避免内存泄漏、空悬指针等问题,并提高代码的效率和可维护性。