动态内存--智能指针

为什么有智能指针

在写程序的时候,经常会使用堆中的内存,但是又特别容易忘记释放这块内存,这就会造成内存泄露。但在我们日常的小编程中,尽管内存泄露,也不会影响我们的程序。这可是一个隐患,在编写大程序的时候容易造成程序崩溃。为了解决这个问题,标准库提供了智能指针类型。功能类似于常规指针,但智能的一点是–当没有指针指向该对象时,会自动释放该对象所占用的堆内存。这就极大的避免程序员因为忘记释放内存而造成内存泄露。

那么我们为什么会使用动态内存呢 ?
  1. 我们不知道程序会使用多少对象。这时数组肯定不能使用了,你只能在程序运行的时候来决定创建多少个对象。
  2. 程序不知道所需对象的准确类型。
  3. 程序需要多少个对象间共享数据。

shared_ptr:允许多个指针指向同一个对象
unique_ptr:独占所指向的对象
weak_ptr: 指向 shared_ptr所管理的对象

如何使用shared_ptr

shared_ptr类

初始化一个 int 类型,name = p1 的智能指针,保存着空指针的智能指针

  shared_ptr<int> p1;    

判断 p1 是否为空

if(p1 && p1->empty()) *p1 = 1;
操作 意义
shared_ptr p 空智能指针,可以指向类型为 T 的对象
p 将 p 用作一个条件判断,若p指向一个对象,则为true
*p 解引用p,获得它指向的对象
swap(p,q) 交换 p 和 q 中的指针
p.unique() 若p.use_count() 为1,返回true,否则返回 false
p.use_count() 返回与p共享的智能指针的数量
p.get() 返回 p 总保存的指针
make_shared 函数

创建一个智能指针。
make_shared 函数的返回值为 shared_ptr 类型。
用默认初始化函数初始化一个int类型的智能指针,name = p。默认初始化的值为 0。

auto p = make_shared<int>();
shared_ptr 的拷贝和赋值

智能指针有一个关联的计数器,每当拷贝一个智能指针的时候,计数器就会增加 1,如果 我们给一个shared_ptr 赋予一个新值的时候,就把的计数器数值 减1,或者 一个shared_ptr 离开了原先的作用域,也就是该shared_ptr 被销毁的时候,计数器也会减 1。

测试样例如下:

int main()
{
        auto p =std::make_shared<int>(42);  // p指向的对象只有 p 一个引用
        use_cout() //方法返回的是与该指针共享对象的智能指针数量
        
        std::cout << p.use_count() << std::endl;  //  1
        {   
                auto q(p);
                std::cout << p.use_count() << std::endl;  // 2
        }   
        std::cout << p.use_count() << std::endl;  // 1
            
        return 0;                                                               
}

和结果一样,如果我们用一个shared_ptr 初始化另外一个shared_ptr,就如测试一样,用p 初始化 q,则p的引用计数 + 1,离开了作用 q 的作用域,也就是 q 自动销毁,则p 的引用计数 - 1

shared_ptr自动销毁

当一个shared_ptr 的计数器的值为 0时,也就是没有智能指向该对象的时候,shared_ptr 会自动调用其析构函数,通过析构函数来释放对象所分配的资源。

shared_ptr 与内置指针的隐式转化

由于shared_ptr 的构造函数被声明为explicit(禁止隐式转换声明),所以 内置指针和智能指针都是禁止隐式转换的。

不要使用相同的内置指针初始化多个智能指针。
#include <iostream>                                                                                                                                      
#include <memory>

using namespace std;

int main()
{
        int *p = new int(1);
        shared_ptr<int> p1(p);
    
        {
                shared_ptr<int> p2(p);
                cout << *p1 << endl; // 1
        }
        cout << *p1 << endl; //0
        
        return 0;
}

如果使多个独立创建的智能指针指向同一块内存,若有一个智能指针被销毁了,那么其他的指针所指向的内存已经被释放。

参考书籍 c++ Primer

猜你喜欢

转载自blog.csdn.net/qq_43701555/article/details/102772715