C++智能指针

智能指针VS传统指针

传统指针:
1.需要手动管理内存
2.容易发生内存泄漏(忘了释放、流程异常导致未释放)
3.释放后没有把变量置为nullptr,容易出现野指针

智能指针

auto_ptr(C++98标准),已不推荐使用

Person *person = new Person(10);
auto_ptr<Person> p(person);
p->display();


auto_ptr<int[]> p1(new int[3]); //会报错,不能用于数组

auto_ptr的基本原理

简单来讲,就是包装了模板和原始指针,在SmartPointer 销毁的时候,将内部的指针销毁

template<typename T>class SmartPointer {
    private:
        T *m_pointer;
    public:
        SmartPointer(T *pointer):m_pointer(pointer){}
        ~SmartPointer(){
            if(m_pointer == nullptr) return;
            delete m_pointer;
            m_pointer = nullptr;
        }

        T *operator->() { //注意这个操作,是为了smartpoint可以调用包装的指针方法
            return m_pointer;
        }
};


int main(){

    {
        Person *person = new Person(10);
        SmartPointer<Person> p(person);
        p->display();
    }
    return 0;
}

shared_ptr

多个shared_ptr可以指向同一个对象,当最后一个shared_ptr在作用域范围内结束时,对象才会被自动释放,并且可以通过一个已经存在的智能指针初始化一个新的智能指针

 shared_ptr<Person> p(new Person(10));
 shared_ptr<Person> p1(p);

shared_ptr<Person[]> persons(new Person[5]{}); //针对数组的用法

shared_ptr 的原理

一个shared_ptr会对一个对象产生强引用(strong reference),每个对象都有个与之对应的强引用计数,记录着当前对象被多少个shared_ptr强引用着,可以通过shared_ptr的use_count函数获得强引用计数,当有一个新的shared_ptr指向对象时,对象的强引用计数就会+1, 当有一个shared_ptr销毁时(比如作用域结束),对象的强引用计数就会-1,当一个对象的强引用计数为0时(没有任何shared_ptr指向对象时),对象就会自动销毁(析构)。

double free 产生的问题,除此之外,shared_ptr 也会产生循环引用问题,因为他是依靠引用计数来判断是否销毁的。

    Person *p = new Person();
    {
        shared_ptr<Person> p1(p);
    }

    {
        shared_ptr<Person> p2(p);
    }

weak_ptr

weak_ptr 的产生是为了解决shared_ptr 出现的循环引用问题,他会对一个对生产生弱引用,不会使引用计数+1。类似oc找那个__weak 解决block的循环引用问题

unique_ptr

unique_ptr也会对一个对象产生强引用,它可以确保同一时间只有1个指针指向对象, 当unique_ptr销毁时(作用域结束时),其指向的对象也就自动销毁了,可以使用std::move函数转移unique_ptr的所有权

unique_ptr<Person> p(new Person());//p强引用Person对象
unique_ptr<Person> p1 = std::move(p);//move后,p1,强引用这Person对象
上一篇:Activity-过渡动画-—-让切换更加炫酷,我崩溃了


下一篇:9、shared_ptr获取原始指针和指定删除器