• 第二讲 auto_ptr智能指针


    auto_ptr 不可被共享,只能指向一个对象

    auto_ptr在构造时获取对某个对象的所有权(ownership),在析构时释放该对象。我们可以这样使用auto_ptr来提高代码安全性:
    int* p = new int(0);
    auto_ptr<int> ap(p);
    从此我们不必关心应该何时释放p, 也不用担心发生异常会有内存泄漏。
    这里我们有几点要注意:
    1) 因为auto_ptr析构的时候肯定会删除他所拥有的那个对象,所有我们就要注意了,一个萝卜一个坑,两个auto_ptr不能同时拥有同一个对象。像这样:
    int* p = new int(0);
    auto_ptr<int> ap1(p);
    auto_ptr<int> ap2(p);
    因为ap1与ap2都认为指针p是归它管的,在析构时都试图删除p, 两次删除同一个对象的行为在C++标准中是未定义的。所以我们必须防止这样使用auto_ptr.
    2) 考虑下面这种用法:
    int* pa = new int[10];
    auto_ptr<int> ap(pa);
    因为auto_ptr的析构函数中删除指针用的是delete,而不是delete [],所以我们不应该用auto_ptr来管理一个数组指针。
    3) 构造函数的explicit关键词有效阻止从一个“裸”指针隐式转换成auto_ptr类型。
    4) 因为C++保证删除一个空指针是安全的, 所以我们没有必要把析构函数写成:
    ~auto_ptr() throw() 
    {
     if(ap) delete ap;
    }

    // STL.cpp : 定义控制台应用程序的入口点。
    //
    //智能指针在其生命周期结束后会自动调用delete
    #include "stdafx.h"
    #include<iostream>
    #include<memory>
    using namespace std;
    
    class WebSite
    {
    public:
        WebSite(int x){i = x;cout << i << "调用构造函数" << endl;}
        ~WebSite(){cout << "调用析构函数" << endl;}
        void output(){cout << "output" << endl;}
    private:
        int i;
    
    };
    int _tmain(int argc, _TCHAR* argv[])
    {
        auto_ptr<WebSite> autop1(new WebSite(4));//定义了一个WebSite类的指针autop1
        auto_ptr<WebSite> autop2(new WebSite(7));
        autop1->output();
        cout << autop1.get() << endl;        //得到auto的一个指针
        cout << autop2.get() << endl;
        //autop1.reset();                        //将auto指向NULL
        //cout << autop1.get() << endl;
        ////autop1->output();                    //reset之后auto不可以再使用了
    
        autop1 = autop2;            //析构原来autop1指向的地址,将autop2指向的之地址赋给autop1。
                                    //也就是说智能指针只能对一个对象并保持该地址
        cout << autop1.get() << endl;
        cout << autop2.get() << endl;
    
        return 0;
    }

    shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针 ,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。shared_ptr也可以安全地放到标准容器中,并弥补了auto_ptr因为转移语义而不能把指针作为STL容器元素的缺陷。

  • 相关阅读:
    angular2怎么使用第三方的库(jquery等)
    线性代数:方程组的几何解释
    2016新的计划
    ES+Hbase对接方案概述
    sparkR操作HDFS上面的CSV文件
    spark1.6配置sparksql 的元数据存储到postgresql中
    spark读写Sequoiadb
    Spring Boot与Docker部署
    Docker中使用Tomcat并部署war工程
    CentOS7安装使用Docker
  • 原文地址:https://www.cnblogs.com/zenseven/p/3805745.html
Copyright © 2020-2023  润新知