• 代理设计模式在auto_ptr及smart_ptr中的体现


    下面这段代码是auto_ptr的实现:

    class Image
    {
    public:
        Image(string name): m_imageName(name) {}
        virtual ~Image() {}
        virtual void Show() {}
    protected:
        string m_imageName;
    };
    class BigImage: public Image
    {
    public:
        BigImage(string name):Image(name) {}
        ~BigImage() {}
        void Show() { cout<<"Show big image : "<<m_imageName<<endl; }
    };
    class BigImageProxy: public Image
    {
    private:
        BigImage *m_bigImage;
    public:
        BigImageProxy(string name):Image(name),m_bigImage(0) {}
        ~BigImageProxy() { delete m_bigImage; }
        void Show() 
        {
            if(m_bigImage == NULL)
                m_bigImage = new BigImage(m_imageName);
            m_bigImage->Show();
        }
    };

          阅读上面的代码,我们可以发现 auto_ptr 类就是一个代理,客户只需操作auto_prt的对象,而不需要与被代理的指针pointee打交道。auto_ptr 的好处在于为动态分配的对象提供异常安全。因为它用一个对象存储需要被自动释放的资源,然后依靠对象的析构函数来释放资源。这样客户就不需要关注资源的释放,由auto_ptr 对象自动完成。实现中的一个关键就是重载了解引用操作符和箭头操作符,从而使得auto_ptr的使用与真实指针类似。

          我们知道C++中没有垃圾回收机制,可以通过智能指针来弥补,下面给出智能指针的一种实现,采用了引用计数的策略。

    template <typename T>
    class smart_ptr
    {
    public:
        smart_ptr(T *p = 0): pointee(p), count(new size_t(1)) { }  //初始的计数值为1
        smart_ptr(const smart_ptr &rhs): pointee(rhs.pointee), count(rhs.count) { ++*count; } //拷贝构造函数,计数加1
        ~smart_ptr() { decr_count(); }              //析构,计数减1,减到0时进行垃圾回收,即释放空间
        smart_ptr& operator= (const smart_ptr& rhs) //重载赋值操作符
        {
            //给自身赋值也对,因为如果自身赋值,计数器先减1,再加1,并未发生改变
            ++*count;
            decr_count();
            pointee = rhs.pointee;
            count = rhs.count;
            return *this;
        }  
        //重载箭头操作符和解引用操作符,未提供指针的检查
        T *operator->() { return pointee; }
        const T *operator->() const { return pointee; }
        T &operator*() { return *pointee; }
        const T &operator*() const { return *pointee; }
        size_t get_refcount() { return *count; } //获得引用计数器值
    private: 
        T *pointee;       //实际指针,被代理  
        size_t *count;    //引用计数器
        void decr_count() //计数器减1
        {
            if(--*count == 0) 
            {
                delete pointee;
                delete count;
            }
        }
    };

    本文出处:http://blog.csdn.net/wuzhekai1985

  • 相关阅读:
    计算机网络
    git学习总结
    MySQL性能优化的21条最佳经验【转】
    为什么Laravel是最成功的PHP框架?
    分布式集群系统下的高可用session解决方案
    浏览器中输入URL到返回页面的全过程
    真正的inotify+rsync实时同步 彻底告别同步慢
    memcache中的add和set方法区别
    php 接口 implements 使用
    Redis的PHP操作手册(自用)
  • 原文地址:https://www.cnblogs.com/hksac/p/7702981.html
Copyright © 2020-2023  润新知