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;
    };


  • 相关阅读:
    微信小程序错误码参考大全
    关于vagrant一个虚拟机搭建多个项目配置(总结)
    Vagrant安装完lnmp后,配置linux和windows共享文件并配置虚拟主机访问项目
    vagrant的centos镜像,怎么用root用户登录?
    Vagrant系列(二)----Vagrant的配置文件Vagrantfile详解
    过滤数组中的空数组array_filter()
    getMessage(),getFile,getLine获取异常用法
    测试工程师的福利!各远程移动测试平台对比分析
    学习这篇总结后,你也能做出天天快报一样的推荐系统
    别被官方文档迷惑了!这篇文章帮你详解yarn公平调度
  • 原文地址:https://www.cnblogs.com/cunyusup/p/14556688.html
Copyright © 2011-2022 走看看