异常安全的智能指针

管理指针成

        在包含指针的类中需要注意复制控制,复制指针时只复制指针中的地址,不会复制指针指向的对象。

          大多数c++类采用三种方法管理指针成员:1)指针成员采用常规指针型行为。

                                                                                     2)采用智能指针

                                                                                     3)采取值型行为

        常规指针缺陷:可能会出现悬垂指针。当一个指针复制到另一个指针,两个指针指向同一个对象,当一个指针删除对象时,另一个指针不知道,所以出现悬垂指针。即使使用默认合成复制构造函数也会出现,类本身无法避免。

        智能指针:加入了引用计数。引用计数跟踪该类有多少对象共享同一指针。当引用计数为0 时,删除对象。创建新类时,初始化指针并将引用计数置为1.进行复制时,增加相应引用计数值。赋值时,减少左操作数所指对象的引用计数的值(减至0,就删除对象),增加右操作数所指对象的引用计数的值。最后,调用析构函数时,减少引用计数的值。如果减至0,就删除对象。

        值型类:复制时会new一个新的副本,指针所指向的对象是唯一的,每个类对象独立管理。

          为了管理具有指针成员的类,必须定义三个复制控制成员:复制构造函数,赋值操作符和析构函数。这些成员可以定义指针成员的指针型行为或者值型行为。

        c++出现内存问题的地方一般:1)缓冲区溢出

                                                              2)悬垂指针/野指针

                                                              3)重复释放

                                                              4)内存泄漏

                                                              5)不配对的 new[]/delete

         都可以通过智能指针很好的解决这些问题,比如:

                                                               1)->用vector/string或者自己写的buffer类管理,自动增加缓冲区大小,用成员函数操作,不直接通过野指针操作

                                                               2),3),4)->可以通过智能指针解决,只在对象析构的时候释放一次内存,引用计数为0的时候才删除指针,自动释放

                                                               5->使用vector,自己释放内存

智能指针模版类

template <class T >
class RefCountedPointer
{
public:
    typedef RefCountedPointer<T> ThisType;  

    RefCountedPointer() :counted_(0),refs_(0)
    {
    }
   
    explicit RefCountedPointer(T* c) :counted_(c),refs_(0) //禁止隐式转化
    {
        std::auto_ptr<T> exception_guard(counted_);  //异常抛出后可以自动释放,异常安全
        if (counted_) {
            refs_ = new size_t(1);
        }
        exception_guard.release();  
    }

    RefCountedPointer(const ThisType& other) :counted_(other.counted_),refs_(other.counted_ ? other.refs_ : 0)
    {
        if (counted_) {
            ++(*refs_);
        }
    }

    ~RefCountedPointer()
    {
        if (refs_ && (--(*refs_) == 0)) {
            delete counted_;
            delete refs_;
        }
    }

    ThisType& assign(T* c)
    {
        ThisType(c).swap(*this);//创建临时对象,退出作用域后自动调用析构函数,异常安全的
        return *this;
    }

    ThisType& assign(const ThisType& other)
    {
        ThisType(other).swap(*this);
        return *this;
    }

    ThisType& operator =(T* c)
    {
        return assign(c);
    }

    ThisType& operator =(const ThisType& rhs)
    {
        return assign(rhs);
    }

    T* operator ->() const
    {
        return counted_;
    }    

    T& operator *() const
    {
        return *counted_;
    }   

    T* get()
    {
        return counted_;
    }

    const T* get() const
    {
        return counted_;
    }

    void swap(ThisType& other)//异常安全,不抛出异常
    {
        std::swap(counted_, other.counted_);
        std::swap(refs_, other.refs_);
    }    

private:
    T* counted_;
    size_t* refs_;//增强程序的可移植性
};


PS参考资料《c++ primer》

          在写一个操作类的时候,开始定义为了常规指针,后来优化重构的时候,看了一些不错的源代码,采用了智能指针,原来一直只有一个概念,使用后比较熟悉和了解了,这也是一个学习的过程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目:– JavaScript 中的患者数据管理系统 患者数据管理系统是为医院开发的 node JS 项目。通过使用此系统,您可以轻松访问患者数据,它具有成本效益,可改善患者护理和数据安全性。不仅如此,它还减少了错误范围。在运行项目之前,您需要下载 node.js。 这个患者数据管理项目包含 javascript、node.js 和 CSS。我们必须让服务器监听端口 3000,并使用 JSON 在客户端和服务器之间交换数据。这个项目会不断询问您有关插件更新的信息,因此请保持互联网畅通。此系统允许您执行 crud 操作。在这里,您是系统的管理员。您还可以添加所需的员工人数。此外,您还可以更新患者记录。该系统功能齐全且功能齐全。 要运行此项目,您需要在计算机上安装NodeJS并使用现代浏览器,例如 Google Chrome、  Mozilla Firefox。ReactJS项目中的此项目可免费下载源代码。有关项目演示,请查看下面的图像滑块。 对于手动安装 1.将主项目文件夹解压到任意目录 2.从 cmd 设置项目目录的路径 3. 输入命令“npm install” 4.完成后输入命令“npm start” 5.现在,您将获得一个 localhost:portnumber,并转到该 URL 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值