美文网首页NDK开发
NDK---C++篇(十)实战----手写智能指针

NDK---C++篇(十)实战----手写智能指针

作者: 初夏的雪 | 来源:发表于2021-06-24 09:59 被阅读0次

    这是我们C++实弹的第二次演习(模仿自定义一个智能指针),这也是我们C++的最后一篇,话不投机半句多,直接开鲁吧。跟着笔者的思路,看着每一步的描述不看代码都可以自己写出来了。

    1、定义一个类

    1)需要存放对象指针(类型不确定),所以是一个模板类;

    2)统计对象的引用数量,需要一个计数器;

    1. 构造函数------每次构造一个智能指针,引用计数都从1开始

    4)析构函数----当引用计数减1 等于0 的时候,需要释放智能指针内部的对象和计数器指针

    template<typename T>
    class CustomPtr{
        
    private :
            T* object;
            int* count;
        
    public:
        //构造函数
        CustomPtr() {
                count = new int(1);
                object = NULL;
            }
        
        //带参的构造函数
        CustomPtr(T *t) : object(t) {
            count = new int(1);
        }
        
        //析构函数
        ~CustomPtr() {
            cout<<"智能指针的析构函数"<<endl;
            if (--(*count) == 0) {
                if (object) {
                    delete object;
                }
                delete count;
                object = NULL;
                count = NULL;
            }
        }
    }
    

    2、给智能指针添加一个拷贝构造函数

     //拷贝构造函数
        CustomPtr(const CustomPtr<T> &p) {
            ++(*p.count);
            object = p.object;
            count = p.count;
        }
    

    3、运算符重载(=)

    特别注意:

    运算符重载时,左侧的对象已经创建好了,再次赋值的时候需要先释放掉创建好的,再进行赋值,否则会出现野对象的问题;

    //运算符重载
        CustomPtr<T> &operator=(const CustomPtr<T> &p) {
            //因为运算符重载,左侧的对象已经创建好了,所以需要释放
            if (--(*count) == 0) {
                if (object) {
                    delete object;
                }
                delete count;
            }
    
            ++(*p.count);
            object = p.object;
            count = p.count;
            return *this;
        }
    

    4、定义一个获取当前引用计数的方法

    int use_count() {
            return *(this->count);
        }
    

    截止目前为止,我们自定义的智能指针已经基本上都完成了,下面来展示一下完整的代码:

    #include <iostream>
    
    using namespace std;
    
    template<typename T>
    class CustomPtr {
    private:
        T *object;
        int *count;
    
    public:
        CustomPtr() {
            count = new int(1);
            object = NULL;
        }
    
        CustomPtr(T *t) : object(t) {
            count = new int(1);
        }
    
        //拷贝构造函数
        CustomPtr(const CustomPtr<T> &p) {
            ++(*p.count);
            object = p.object;
            count = p.count;
        }
    
        //运算符重载
        CustomPtr<T> &operator=(const CustomPtr<T> &p) {
            //因为运算符重载,左侧的对象已经创建好了,所以需要释放
            if (--(*count) == 0) {
                if (object) {
                    delete object;
                }
                delete count;
            }
    
            ++(*p.count);
    
            object = p.object;
            count = p.count;
            return *this;
        }
    
        ~CustomPtr() {
            cout<<"智能指针的析构函数"<<endl;
            if (--(*count) == 0) {
                if (object) {
                    delete object;
                }
                delete count;
                object = NULL;
                count = NULL;
            }
        }
    
    
        int use_count() {
            return *(this->count);
        }
    
    };
    

    5、定义“子弹”---Person类

    class Person{
    public:
        ~Person(){
            cout<<"析构函数调用"<<endl;
        }
    };
    

    6、实弹射击

    int main(){
        
        /**
         * 手写智能指针
         */
    
        Person* person=new Person();
        Person* person1=new Person();
    
        /**
         * 智能指针的构造函数,计数+1
         */
        cout<<"-----1-------"<<endl;
        CustomPtr<Person> customPtr(person);
        cout<<"构造函数执行后:"<<customPtr.use_count()<<endl;
    
        /**
         * 拷贝构造函数   计数+1
         */
        cout<<"-----2-------"<<endl;
        CustomPtr<Person> customPtr1(customPtr);
        cout<<"拷贝构造函数执行后:"<< customPtr1.use_count()<<endl;
    
        /**
         * 拷贝构造函数,计数+1
         */
        cout<<"-----3-------"<<endl;
        CustomPtr<Person> customPtr2=customPtr;
        cout<<customPtr2.use_count()<<endl;
    
        /**
         * 运算符重载  计数+1(会先创建一个对象,然后再运算符重载中释放已经创建好的默认对象,然后再赋值)
         */
        cout<<"-----4-------"<<endl;
        CustomPtr<Person> customPtr3;
        customPtr3=customPtr;
        cout<<customPtr3.use_count()<<endl;//
    
        /**
         * 运算符重载,计数+1
         * 特别注意:如果在运算符重载中,不释放智能指针中的源对象person1 ,会导致person1对象成为野对象,无法释放,必须要手动释放delete
         */
    
        cout<<"-----5-------"<<endl;
        Person* person2=new Person();
        CustomPtr<Person> customPtr4(person2);
        CustomPtr<Person> customPtr5(person1);
        customPtr5=customPtr4;
        cout<<customPtr5.use_count()<<endl;
    
        return 0;
    }
    
    
    //输出结果就自己去玩了
    

    好了,截止今天,我们C++的学习就暂时告一段落了,多动手敲一下,复制了代码后,自己多修改玩玩,可以加深印象。后面我们就进入JNI开发了。

    相关文章

      网友评论

        本文标题:NDK---C++篇(十)实战----手写智能指针

        本文链接:https://www.haomeiwen.com/subject/ddqyjltx.html