第9章:智能指针

1,智能指针的使用
2,源码

#include <iostream>
#include <memory>
#include <list>
#include <vector>

/*
1,智能指针
smart_point:智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象
shared_ptr:允许多个指针指向同一个对象
unique_ptr:独占所指向的对象
2,操作方式
shared_ptr unique_ptr: 共享函数
    p:          将p用作一个条件判断,若p指向一个对象,则为true
    *p:         解引用p,获得它指向的对象
    p->mem:      等价于(*p).mem
    p.get():     返回p中所保存的指针,要小心使用,若智能指针释放了其对象,返回的指针所指向的对象也就消失了
    swap(p, q); p.swap(q):  交换p和q中的指针
shared_ptr:独有的操作
    make_shared<T>(args): 返回一个shared_ptr,指向一个动态分配的类型为T的对象,使用args初始化此对象
    shared_ptr<T>p(q):    p是shared_ptr q的拷贝,此操作会递增q中的计数器,q中的指针必须能转换成T*
    p.unique():           若p。use_count()为1,返回true;否则返回false
    p.use_count():        返回与p共享对象的智能指针数量,可能很慢
3,动态内存使用原因
    程序不知道自己需要使用多少对象   容器类的使用时出于这个原因
    程序不知道所需对象的准确类型
    程序需要在多个对象间共享数据
4,unique_ptr操作函数:
    unique_ptr<T> u1:      空unique_ptr可以指向类型为T的对象,u1会使用delete
    u = nullptr     :      释放u指向的对象,将u置为空
    u.release()     :      u放弃对指针的控制权,返回指针,并将u置为空; 并不会释放指针
    u.reset()       :      释放u指向的对象
    u.reset(q)      :      如果提供了内置指针q,令u指向这个对象;否则将u置为空
    u.reset(nullptr):
5,new T[]          :      动态分配数组
6,allocator类:
    allocator<T> a         :      定义一个名为a的allocator对象,它可以为类型为T的对象分配内存
    a.allocate(n)          :      分配一段原始的,未构造的内存,保存n个类型为T的对象
    a.deallocate(p,n)      :      释放从T*指针p中地址开始的内存
    a.construct(p, args)   :      p必须是一个类型为T*的指针,指向一块原始内存,arg被传递给类型weiT的构造函数
    a.destroy(p)           :      p为T*类型的指针,此算法对p指向的对象执行西沟函数
*/

using namespace std;
int main()
{
    /*shared_ptr初始化定义-----------------------------------------------------------------*/
    shared_ptr<string>    p1;                       //shared_ptr,可以指向string
    shared_ptr<list<int>> p2;                       //shared_ptr,可以指向int的list

    if (p1 && p1->empty())
    {
        cout << "No Empty" << endl;
    }
    else
    {
        cout << "Empty" << endl;
    }

    //make_shared用其参数来构造给定类型的对象
    shared_ptr<int>p3    = make_shared<int>(4);          //指向一个值为4的int的shared_ptr指针
    shared_ptr<string>p4 = make_shared<string>(10, '9'); //指向10个9的string的shared_ptr指针
    shared_ptr<int>p5    = make_shared<int>();           //指向一个值为0的int的shared_ptr指针
    auto p6              = make_shared<vector<string>>();//动态分配一个空的string


    /*shared_ptr的拷贝和赋值---------------------------------------------------------------*/
    /*每个shared_ptr都有一个关联的计数器,通常称其为引用计数,无论何时我们拷贝一个shared_ptr计数器都会递增,
      当我们给shared_ptr赋予一个新值或是shared_ptr被销毁,计数器会递减,当计数器变为0,它就会自动释放自己所
      管理的对象
    */
    auto p7   = make_shared<int>(42);                //p7指向的对象只有p7一个引用者
    auto q(p7);                                      //p7和q指向相同对象,此对象有两个引用


    /*unique_ptr指向它所指的对象,当它被销毁时它所指的对象也被销毁----------------------------------*/
    //当我们定义unique_ptr时,需要将其绑定到new返回的指针上,unique_ptr不支持普通的拷贝和赋值操作
    unique_ptr<int> p8(new int(42));                 //p8指向一个值为42的int
    p8 = nullptr;                                    //释放指针,将p8置为空

    unique_ptr<string> p9(new string("hello point"));
    unique_ptr<string> p10(p9.release());            //将p9的所有权转移给p10
    unique_ptr<string> p11(new string("Text"));
    p10.reset(p11.release());                        //将所有权从p11转到p10;reset释放了p10原来指向的内存

    /*new T[]动态数组----------------------------------------------------------------------*/
    int *pa      = new int;
    int *pia     = new int[10];                          //10个未初始化的int
    int *pia2    = new int[10]();                        //10个值初始化为0的int
    string *psa  = new string[10];                       //10个空string
    string *psa2 = new string[10]();                     //10个空string

    int    *pia3 = new int[10]{0,1,2,3,4,5,6,7,8,9};     //10个int分别进行初始化
    string *psa3 = new string[10]{"a", "an", "the", string(3, 'x')}; //前4个进行初始化

    delete pa;                                          //释放指针动态分配的对象

    delete [] pia;                                       //释放动态分配的数组
    delete [] pia2;
    delete [] pia3;

    delete [] psa;
    delete [] psa2;
    delete [] psa3;

    /*unique_ptr分配数组------------------------------------------------------------------*/
    unique_ptr<int[]> up(new int[10]);                      //up指向一个包含10未初始化int的数组
    for (size_t i=0; i<10; i++)
    {
        up[i] = i;
    }
    up.release();                                           //自动用delete[]销毁其指针


    /*shared_ptr管理动态数组,shared_ptr不直接支持管理动态数组,如果希望使用shared_ptr管理,必须提供自
     * 己定义的删除器----------------------------------------------------------------------*/
    shared_ptr<int> sp(new int[10], [] (int *p) {delete[] p;});
    sp.reset();                                             //使用我们提供的lambda释放数组,他是用detete[]


    /*allocatro使用---------------------------------------------------------------------*/
    allocator<string> alloc;                                //可以分配string的allocator对象
    auto const p = alloc.allocate(10);                      //分配n个未初始化的string

    auto m = p;                                             //q指向最后构造的元素之后的位置
    alloc.construct(m++);                                   //*q为空字符串
    alloc.construct(m++, 10, 'c');                          //*q为cccccccc
    alloc.construct(m++, "hi");                             //*q为hi

    while (m != p)
    {
        cout << *(--m) << endl;
        alloc.destroy(m);                                  //释放真正构造的string
    }


    return 0;
}

猜你喜欢

转载自blog.csdn.net/ksmtnsv37297/article/details/89444947