传统指针:
1.需要手动管理内存
2.容易发生内存泄漏(忘了释放、流程异常导致未释放)
3.释放后没有把变量置为nullptr,容易出现野指针
智能指针
Person *person = new Person(10); auto_ptr<Person> p(person); p->display(); auto_ptr<int[]> p1(new int[3]); //会报错,不能用于数组
简单来讲,就是包装了模板和原始指针,在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<Person> p(new Person(10)); shared_ptr<Person> p1(p); shared_ptr<Person[]> persons(new Person[5]{}); //针对数组的用法
一个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 的产生是为了解决shared_ptr 出现的循环引用问题,他会对一个对生产生弱引用,不会使引用计数+1。类似oc找那个__weak 解决block的循环引用问题
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对象