• 【足迹C++primer】39、动态内存与智能指针(3)


    动态内存与智能指针(3)
    /**
    * 功能:动态内存与智能指针
    * 时间:2014年7月8日15:33:58
    * 作者:cutter_point
    */
    
    
    #include<iostream>
    #include<vector>
    #include<memory>
    #include<string>
    
    using namespace std;
    /**
    智能指针和异常
    */
    void f()
    {
        shared_ptr<int> sp(new int(42));        //分配一个新对象
        //这段代码抛出一个异常,且在f中未被捕获
    }//在函数结束时shared_ptr自己主动释放内存
    
    /*
    函数退出有两种可能,正常处理结束或者发生了异常,不管哪种情况,局部对象都会被销毁
    */
    
    //当发生异常的时候,我们直接管理的内存是不会直接释放的
    void fun1()
    {
        int *ip=new int(42);        //动态分配一个新对象
        //这段代码抛出一个异常。且在fun1中未被捕获
        delete ip;      //在退出之前释放内存
    }
    
    /**
    智能指针和哑类
    */
    struct destination{};     //表示我们正在连接什么;
    struct connection{};      //使用连接所需的信息;
    connection connect(destination*){}   //打开连接
    void disconnect(connection){}        //关闭给定的链接
    void f(destination &d/* 其它參数 */)
    {
        //获得一个链接;记住使用完后要关闭它
        connection c=connect(&d);
        //使用连接
        //假设我们在f退出前忘记调用disconnect,就无法关闭c了
    }
    
    /**
    使用我们自己的释放操作
    */
    void end_connection(connection *p){disconnect(*p);}
    
    void fun2(destination &d/* 其它參数 */)
    {
        connection c=connect(&d);
        shared_ptr<connection> p(&c, end_connection);
        //使用连接
        //当fun2退出的时候(即使是因为异常退出),connection会被正确关闭
    }
    
    /**
    unique_ptr
    */
    //初始化unique_ptr必须採用直接初始化形式
    //因为一个unique_ptr拥有它指向的对象。因此unique_ptr不支持普通的拷贝或赋值操作
    void fun3()
    {
        unique_ptr<string> p1(new string("Stegosaurus"));
    //    unique_ptr<string> p2(p1);  //错误:unique_ptr不支持拷贝
        unique_ptr<string> p3;
    //    p3=p2;                      //错误:unique_ptr不支持赋值
    }
    
    void fun4()
    {
        unique_ptr<string> p1(new string("Stegosaurus"));
    //    unique_ptr<string> p2(p1);  //错误:unique_ptr不支持拷贝
    //    unique_ptr<string> p3;
    //    p3=p2;                      //错误:unique_ptr不支持赋值
        //将全部权从p1(指向string Stegosaurus)转移给p2
    
        unique_ptr<string> p2(p1.release());    //release将p1置为空
        unique_ptr<string> p3(new string("Text"));
        //将全部权从p3转移到p2
        p2.reset(p3.release()); //reset释放了p2原来指向的内存
    }
    
    /**
    传递unique_ptr參数和返回unique_ptr
    */
    //返回一个unique_ptr
    unique_ptr<int> clone(int p)
    {
        //正确:从int*创建一个unique_ptr<int>
        return unique_ptr<int>(new int(p));
    }
    
    //返回一个局部对象拷贝
    unique_ptr<int> fun5(int p)
    {
        unique_ptr<int> ret(new int(p));
        //...
        return ret;
    }
    
    /**
    向unique_ptr传递删除器
    */
    
    /*
    void fun6()
    {
        //p指向一个类型为objT的对象。并使用一个类型为delT的对象释放objT对象
        //他会调用一个fcn的delT类型对象
        using objT=int;
        using delT=int;
        delT fcn;
        unique_ptr<objT, delT> p(new objT,fcn);
    }
    有问题。!!

    !应该用lambda */ /* void fun7(destination &d /* 其它參数//* ) { connection *pc; connection c=connect(&d); //打开连接 //当p被销毁时候。连接将会关闭 unique_ptr<connection, decltype(end_connection)*) p(&c, end_connection); //使用连接 //当fun7退出时,即使是异常退出,连接也会正常关闭 } */ /** weak_ptr */ //weak_ptr是一种不控制所指向对象生存期的智能指针,它指向一个shared_ptr //管理的对象 //当我们创建一个weak_ptr时,要用一个shared_ptr来初始化它 void fun8() { auto p=make_shared<int>(42); weak_ptr<int> wp(p); //wp弱共享p;p的引用计数未改变 /* 因为对象可能不存在,我们不能使用weak_ptr直接訪问对象,而必须调用lock. lock返回一个指向共享对象的shared_ptr. */ if(shared_ptr<int> np=wp.lock()) { //假设np不为空则条件成立 //if中,np与p共享对象 } } /** 核查指针类 */ /* 通过使用weak_ptr,不会影响一个给定的StrBlob所指向的vector的生存期。 可是,能够阻止用户訪问一个不再存在的vector的企图 */ //对于訪问一个不存在的元素的尝试。StrBlobPtr抛出一个异常 class StrBlobPtr { public: StrBlobPtr():curr(0) {} StrBlobPtr(StrBlob &a, size_t sz=0):wptr(a.data),curr(sz){} string& deref() const; StrBlobPtr &incr(); //前缀递增 private: //若检查成功,check返回一个指向vector的shared_ptr shared_ptr<vector<string>> check(size_t, const string&) const; //保存一个weak_ptr, 意味着底层vector可能会被销毁 weak_ptr<vector<string>> wptr; size_t curr; //在数组中的当前位置 }; int main() { return 0; }


    PS:不要问我。为什么要这样写,由于我基本吧要写的都写到里面去了,能够看出我是先打好草稿再往上传的,可是有个问题这节确实是有点乱,好多我搞半天就是实现不了,上网查别人也是这样写。但我就是不能搞出来。我不知道是哪根筋没跳对- -,总之先看过再说,以后回头再看的时候应该会知道吧,事实上如今看到从前写的那些认为比較难的。如今看来似乎没那么难了,基本如今非常轻松就能够搞出来,我是不是有点小进步呢!

    大笑

  • 相关阅读:
    【数据结构第二周】队列知识点整理
    【数据结构第二周】堆栈知识点整理
    【数据结构第二周】线性表知识点整理
    【数据结构第一周】最大子列和问题整理
    网络设置
    QT 安装教程
    C# 复制粘贴板 多行粘贴
    设置网络适配器IP优先级
    MySQL 查重复单号和删重复单号
    Mysql 10053 SocketException 你的主机中的软件中止了一个已建立的连接。
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5276758.html
Copyright © 2020-2023  润新知