智能指针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对象