C++智能指针介绍与使用

什么是智能指针

智能指针是一种 C++ 标准库中的模板类,用于管理动态分配内存资源。它们提供了自动化的内存管理功能,可以帮助程序员在避免内存泄漏和野指针的同时,简化内存资源的手动释放。C++ 标准库中提供了三种主要的智能指针:std::shared_ptr、std::unique_ptr 和 std::weak_ptr。

智能指针的原理

shared_ptr采用了引用计数器,允许多个指针指向同一个对象。每一个shared_ptr的拷贝都指向相同的内存,并共同维护同一个引用计数器,记录同一个实例被引用的次数。每使用他一次,内部的引用计数加1,每析构一次,内部的引用计数减1,减为0时,自动删除所指向的堆内存。shared_ptr内部的引用计数是线程安全的,但是对象的读取需要加锁。

1、std::shared_ptr:

  • shared_ptr在内部会维护着一份引用计数,用来记录该份资源被几个对象共享。
  • 当一个shared_ptr对象被销毁时(调用析构函数),析构函数内就会将该计数减1。
  • 如果引用计数减为0后,则表示自己是最后一个使用该资源的shared_ptr对象,必须释放资源。
  • 如果引用计数不是0,就说明自己还有其他对象在使用,则不能释放该资源,否则其他对象就成为野指针。
class MyClass {
public:
    std::shared_ptr<MyClass> ptr;

    MyClass() {
        std::cout << "构造函数" << std::endl;
    }
    ~MyClass() {
        std::cout << "析构函数" << std::endl;
    }
};

int main(int argc, char argv)
{
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    std::shared_ptr<MyClass> ptr2 = std::make_shared<MyClass>();

    return 0;
}

输出结果:
C++智能指针介绍与使用_第1张图片

注意,在使用std::shared_ptr有可能导致循环引用问题,如:

class MyClass {
public:
    std::shared_ptr<MyClass> ptr;

    MyClass() { std::cout << "构造函数" << std::endl; }
    ~MyClass() { std::cout << "析构函数" << std::endl; }
};

int main() {
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    std::shared_ptr<MyClass> ptr2 = std::make_shared<MyClass>();

    ptr1->ptr = ptr2; // ptr1 持有 ptr2 的引用
    ptr2->ptr = ptr1; // ptr2 持有 ptr1 的引用

    std::cout << ptr1.use_count() << std::endl;
    std::cout << ptr2.use_count() << std::endl;

    return 0;
}

输出结果:
C++智能指针介绍与使用_第2张图片

2、std::unique_ptr:

  • std::unique_ptr 是一种独占所有权的智能指针,确保只有一个指针指向一个对象。
  • 它直接将拷贝构造函数和赋值重载函数给禁用掉,因此,不让其进行拷贝和赋值。
  • 它通过将所有权转移给新指针或释放给定对象来管理动态内存。
class MyClass {
public:
    MyClass() { std::cout << "构造函数" << std::endl; }
    ~MyClass() { std::cout << "析构函数" << std::endl; }

    void function() { std::cout << "函数调用" << std::endl; };
};


int main(int argc, char argv)
{
    std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>();
    // std::unique_ptr ptr2 = ptr1;    // 报错

    // 不能直接进行拷贝,但可以进行移动赋值
    std::unique_ptr<MyClass> ptr2 = std::move(ptr1);
    ptr2->function();

    return 0;
}

输出结果:
C++智能指针介绍与使用_第3张图片

3、std::weak_ptr:

  • std::weak_ptr 是一种弱引用智能指针,不会增加对象的引用计数。
  • 它通常用于解决循环引用的问题,通过检查对象是否仍然存在来避免访问无效的指针。
class MyClass {
public:
    std::shared_ptr<MyClass> ptr;
    MyClass() { std::cout << "构造函数" << std::endl; }
    ~MyClass() { std::cout << "析构函数" << std::endl; }
    void function() { std::cout << "函数调用" << std::endl; };
};

int main(int argc, char argv)
{
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    std::weak_ptr<MyClass> ptr2 = ptr1;
    std::cout << "ptr1 user count = " << ptr1.use_count() << std::endl;

    if (auto lockedPtr = ptr2.lock()) 
        lockedPtr->function();
    else
        std::cout << "对象已被释放" << std::endl;    
    return 0;
}

输出结果:
C++智能指针介绍与使用_第4张图片

你可能感兴趣的:(linux,c++)