C++11智能指针

普通指针的不足

  1. new和new[]的内存需要用delete和delete[]释放。
  2. 程序员的主观失误,忘了或漏了释放。
  3. 程序员也不确定何时释放。

普通指针的释放

  1. 类内的指针,在析构函数中释放。
  2. C++内置数据类型,如何释放?
  3. new出来的类,本身如何释放?

指针指针的设计思路

  1. 智能指针是类模板,在栈上创建智能指针对象。

  2. 把普通指针交给智能指针对象。

  3. 智能指针对象过期时,调用析构函数释放普通指针的内存。

智能指针的类型

  1. auto_ptr是C++98的标准,C++17已弃用。
  2. unique_ptr、shared_ptr和weak_ptr是C++11标准。

智能指针unique_ptr

unique_ptr独享它指向的对象,也就是说,同时只有一个unique_ptr指向同一个对象,当这个unique_ptr被销毁时,指向的对象也随时被销毁。

包含头文件:#include

示例

#include 
#include 
#include 
using namespace std;

class AA
{
 public:
    string m_name;
    AA(){cout << "init AA " << endl;}
    AA(const string& name):m_name(name){cout << "init AA and param " << endl;}
    ~AA(){cout << "desctory AA" << endl;}
}

int main()
{
    //第一种方式
    AA* P=new AA("aaa");
    unique_ptr pu1(p);
    cout << "m_name" << (*pu1).m_name << endl;
    cout << "m_name" << pu1.m_name << endl;
    
    //第二种方式
     unique_ptr pu2=make_unique("aaa");
    
    //第三方方式
    unique_ptr pu3=make_unique(new AA("aaa"));

}
  1. 将一个unique_ptr赋给另一个时,如果源unique_ptr是一个临时右值,编译器允许这样做;如果源unique_ptr将存在一段时间,编译器禁止这样做。一般用于函数的返回值。

    unique_ptr p0;

    p0=unique_ptr(new AA("aaa"));

  2. 用nullptr给unique_ptr赋值将释放对象,空的unique_ptr==nullptr;

  3. release()释放对指针的控制权,将unique_ptr置为空,返回裸指针。(可用于把unique_ptr传递给子函数,并且在子函数中释放对象)

  4. std::move()可以转移对指针的控制权。(可用于把unique_ptr传递给子函数,子函数形参也是unique_ptr)

  5. reset()释放对象

    void rest(T* _ptr=(T*)nullptr);

    pp.reset(); //释放pp对象指向的资源对象

    pp.reset(nullptr); //释放pp对象指向的资源对象

    pp.reset(new AA("bbb")); //释放pp指向的资源对象,同时指向新的对象

  6. swap()交换两个unique_ptr的控制权

    void swap(unique_ptr &_Right);

  7. unique_ptr也可像普通指针那样,当指向一个类继承体系的基类对象时,也具有多态性质,如同使用裸指针管理基类对象和派生类对象那样。

  8. unique_ptr不是绝对安全,如果程序中调用exit()退出,全局的unique_ptr可自动释放,但局部的unique_ptr无法释放。

  9. unique_ptr提供了支持数组的具体化版本。

    数组版本的unique_ptr,重载了操作符[],操作符返回的引用,可以作为左值使用。

智能指针shared_ptr

shared_ptr共享它指向的对象,多个shared_ptr可以指向(关联)相同的对象,在内部采用的计数机制来实现。

当心的shared_ptr与对象关联时,引用计数增加1;

当shared_ptr超出作用域时;引用计数减1。当引用计数变为0,则表示没有任何shared_ptr与对象关联,则释放该对象。

基本用法

shared_ptr的构造函数也是explicit,但是,没有删除构造函数和赋值函数。

初始化

方法一:

shared_ptr p0(new AA("aaa"));

方法二:

shared_ptr p0=make_shared("aaa");

方法三:

AA* p=new AA("aaaa");

shared_ptr p0(p);

方法四:

shared_ptr p0(new AA("aaa"));

shared_ptr p1(p0);

shared_ptr p2=p1;

智能指针weak_ptr

shared_ptr存在的问题

shared_ptr内部维护一个共享的引用计数器,多个shared_ptr可以指向同一个资源。

如果出现了循环引用的情况,引用计数永远无法归0,资源不会被释放。

weak_ptr没有重载->个*操作符,不能直接访问资源。

有以下成员函数:

1)operator=() //把shared_ptr或weak_ptr赋值给weak_ptr;

2)expired(); //判断它指资源是否已过期(已经被销毁);

3)lock();//返回shared_ptr,如果资源已经过期,返回空的shared_ptr。

4)reset (); //将当前weak_ptr指针置为空。

5)swap(); //交换

智能指针的删除器

在默认情况下,智能指针过期的时候,用delete原始指针;释放它管理的资源。程序员可以自定义删除器,改变智能指针释放的资源的行为。删除器可以时全局函数、仿函数和Lambda表达式,形参为原始指针。

void deleteFunc(AA* a)
{
    delete a;
}

int main()
{
    shared_ptr pa1(new AA("aaa"),deleteFunc);
    return 0;
}

你可能感兴趣的:(C++11智能指针)