NDK开发

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

2021-06-24  本文已影响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开发了。

上一篇下一篇

猜你喜欢

热点阅读