zoukankan      html  css  js  c++  java
  • C++智能指针

    template<typename T>
    class Auto_ptr1
    {
    public:
        Auto_ptr1(T* ptr = nullptr):     //相当于传入的是new resource的指针 名称ptr
                m_ptr{ptr}   //通过参数列表赋值给m_ptr 这是整个是一个构造函数
        {}
    
        virtual ~Auto_ptr1()   //大部分析构都是虚函数
        {
            delete m_ptr;     //在析构函数中delete,
        }
    
        T& operator*() { return *m_ptr; }  //对*和->进行重载,因为类的话不支持*和->
        T* operator->() { return m_ptr; }
    private:
        T* m_ptr;
    };
    
    class Resource
    {
    public:
        Resource() { cout << "Resource acquired!" << endl; }
        virtual ~Resource() { cout << "Resource destoryed!" << endl; }
    };
    int main()
    {
        {
            Auto_ptr1<Resource> res(new Resource);  // 传入的是一个类的指针
        }
    
        cin.ignore(10);
        return 0;
    }
    Auto_ptr1<Resource> res(new Resource)和vector<int> vec(n)一样的都是模板类型的运用,一起记非常好记
    Auto_ptr1<Resource> res1(new Resource);
    Auto_ptr1<Resource> res2(res1);

    还有问题:因为用res1初始化res2,调用的是默认复制构造函数,执行的是浅复制。所以,res2与res1内部保存是同一块内存,当销毁变量时,同一块内存将会被多次释放,程序当然会奔溃!!
    template<typename T>
    class Auto_ptr2
    {
    public:
        Auto_ptr2(T* ptr = nullptr) :
                m_ptr{ ptr }
        {}
    
        virtual ~Auto_ptr2()
        {
            delete m_ptr;
        }
    
        Auto_ptr2(Auto_ptr2& rhs)
        {
            m_ptr = rhs.m_ptr;      //这两行表示将指针的所有权转移给了新的指针类,因为不能出现两个指针类指向同一个区域的情况,所以将之前的指针指向NULL
            rhs.m_ptr = nullptr;
        }
    
        Auto_ptr2& operator=(Auto_ptr2& rhs) //这个是重载 = 号,原理和上面的拷贝构造函数一样的
        {
            if (&rhs == this)
                return *this;
    
            delete m_ptr;
            m_ptr = rhs.m_ptr;
            rhs.m_ptr = nullptr;
            return *this;
        }
    
        T& operator*() { return *m_ptr; }
        T* operator->() { return m_ptr; }
        bool isNull() const { return m_ptr == nullptr; }
    private:
        T* m_ptr;
    };

    template<typename T>
    class Auto_ptr3
    {
    public:
        Auto_ptr3(T* ptr = nullptr):
                m_ptr{ptr}
        {}
    
        Auto_ptr3(const Auto_ptr3& rhs) = delete; // = delete表示不能被调用,这个定义在前,为了检查是不是const进入了拷贝构造函数,因为const不能改变,防止报错
    
        Auto_ptr3(Auto_ptr3&& rhs) :  // &&右值引用 
                m_ptr{ rhs.m_ptr }
        {
            rhs.m_ptr = nullptr;
        }
    
        Auto_ptr3& operator=(const Auto_ptr3& rhs) = delete;
    
        Auto_ptr3& operator=(Auto_ptr3&& rhs)
        {
            if (this == &rhs)
            {
                return *this;
            }
            std::swap(m_ptr, rhs.m_ptr);
            return *this;
    
        }
    
        virtual ~Auto_ptr3()
        {
            delete m_ptr;
        }
    
        T& operator*() { return *m_ptr; }
        T* operator->() { return m_ptr; }
    
        bool isNull() const { return m_ptr == nullptr; }
    private:
        T* m_ptr;
    };


  • 相关阅读:
    ZOJ 2588 Burning Bridges
    POJ 1966 ZOJ 2182 Cable TV Network
    HDU 5348 MZL's endless loop
    HDU 5352 MZL's City
    Tarjan算法求解无向连通图的割点、割边、点双连通分量和边双连通分量的模板
    ZOJ 1119 SPF
    HDU 3452 Bonsai
    HDU 1520 Anniversary party
    POJ 2239 Selecting Courses
    POJ 1144 Network
  • 原文地址:https://www.cnblogs.com/cunyusup/p/14556688.html
Copyright © 2011-2022 走看看