zoukankan      html  css  js  c++  java
  • C++ 智能指针的简单实现

    • 智能指针的用处:在c++中,使用普通指针容易造成堆内存的泄露问题,即程序员会忘记释放,以及二次释放,程序发生异常时内存泄漏等问题,而使用智能指针可以更好的管理堆内存。注意,在这里智能指针是一个类而非真正的指针,只是对一个真正的指针进行包装,代理原指针。通过操作符的重载,可以让智能指针和真正的指针有类似的操作。
    • 如何实现:在智能指针析构函数当中,可以对代理的原指针进行delete以及赋空指针等操作,智能指针销毁时,自动调用析构函数,省去了程序员自己管理指针的操作。当多个智能指针代理同一个指针时,我们要引入一个计数器,用来计数智能指针的个数,最后一个销毁的智能指针有义务对原指针进行销毁工作,具体实现代码如下:

       

    template<class T>
    class Smart_ptr {
    public:
        Smart_ptr(T*ptr);
        Smart_ptr(const Smart_ptr &ptr);//拷贝构造函数
        ~Smart_ptr();//析构函数
        int get_cnt();//获得当前代理原指针的智能指针个数
        Smart_ptr& operator=(const Smart_ptr&ptr);//赋值操作
        T& operator *();//指针操作
        T* operator ->();//指针操作
    private:
        T*_ptr;
        int*_cnt;
    };
    template<class T>
    Smart_ptr<T>::Smart_ptr(T*ptr):_ptr(ptr) {//判断参数指针是否为空;不为空,计数+1
        if (_ptr) _cnt = new int(1);
        else _cnt = new int(0);
    }
    template<class T>
    Smart_ptr<T>::Smart_ptr(const Smart_ptr &ptr) {//复制构造函数,复制成功,计数加1
        if (this != &ptr) {
            this->_ptr = ptr._ptr;
            this->_cnt = ptr._cnt;
            (*this->_cnt)++;
        }
    }
    template<class T>
    Smart_ptr<T>::~Smart_ptr() {//若当前的智能指针是最后一个代理指针,负责销毁原指针
        (*this->_cnt)--;
        if ((*this->_cnt) == 0) {
            delete this->_cnt;
            delete this->_ptr;
            _cnt = nullptr;
            _ptr = nullptr;
        }
    }
    template<class T>
    Smart_ptr<T>& Smart_ptr<T>::operator=(const Smart_ptr&ptr) {//1:若赋值前后代理的指针是一样的,直接返回即可2:先判断当前的智能指针是否为最后一个代理原指针的智能指针,若是,销毁原指针;
        if (this->_ptr == ptr._ptr)return *this;//3:当前智能指针将代理一个新的指针
        if (this->_ptr != nullptr) {
            (*this->_cnt)--;
            if (*this->_cnt == 0) {
                delete this->_cnt;
                delete this->_ptr;
            }
        }
        this->_cnt = ptr._cnt;
        this->_ptr = ptr._ptr;
        (*this->_cnt)++;
        return *this;
    }
    template<class T>
    T& Smart_ptr<T>::operator *() {//指针操作
        return *(this->_ptr);
    }
    template<class T>
    T* Smart_ptr<T>::operator->() {//指针操作
        return this->_ptr;
    }
    template<class T>
    int Smart_ptr<T>::get_cnt() {
        return *this->_cnt;
    }

    main函数:

    int main() {
        Smart_ptr<int>sp1(new int(1));
        cout <<"sp1.cnt:"<< sp1.get_cnt() << endl;
        Smart_ptr<int>sp2(sp1);
        cout << "sp1.cnt:" << sp1.get_cnt() << endl;
        Smart_ptr<int>sp3(new int(10));
        cout << "sp3.cnt:" << sp3.get_cnt() << endl;;
        sp3 = sp2;
        cout << "sp3.cnt:" << sp3.get_cnt() << endl;
        return 0;
    }

    调用结果:

  • 相关阅读:
    flash put_movie loadmovie 区别
    1.低权限的程序向高权限的程序发消息 2.慎用setcurrentdirectory
    宽字符转窄字符CW2AEX<>(szAreaInfo,CP_UTF8)
    查看内存的方法。vs-调试-窗口-内存
    xx.exe 中的 0x014180bd 处有未经处理的异常: 0xC0000005: 读取位置 0xfeeefeee 时发生访问冲突(当指针访问异常时,应考虑是不是对象未创建)。
    获取文件版本(IE)
    /MD, /MT, /LD (Use Run-Time Library)
    我是一块主板 《转载》
    我是一块声卡 《转载》
    我是一块硬盘 《转载》
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/9465341.html
Copyright © 2011-2022 走看看