文章目录
C++中的智能指针(Smart Pointer)
1. 介绍
-
传统指针存在的问题:
- 需要手动管理内存;
- 容易发生内存泄露(忘记释放、出现异常等);
- 释放之后产生野指针。
-
智能指针就是为了解决传统指针存在的问题:
auto_ptr
:属于C++98标准,在C++11中已经不推荐使用(有缺陷,比如不能用于数组);shared_pt
:属于C++11标准;unique_prt
:属于C++11标准。
2. 智能指针的简单自实现
template<class T>
class SmartPointer {
T *m_pointer;
public:
SmartPointer(T *pointer):m_pointer(pointer) { }
~SmartPoiner() {
if(m_pointer == nullptr) return;
delete m_pointer;
}
T *operator->() {
return m_pointer;
}
};
3. shared_ptr
-
shared_ptr
的设计理念:- 多个
shared_ptr
可以指向同一个对象,当最后一个shared_ptr
在作用域范围内结束时,对象才会被自动释放。
- 多个
-
可以通过一个已存在的智能指针初始化一个新的智能指针:
shared_ptr<Person> p1(new Person())
;shared_ptr<Person> p2(p1)
;
-
针对数组的用法:
shared_ptr<Person> ptr1(new Person[5]{}, [ ] (Person *p) { delete[] p; })
;
shared_ptr<Person[]> person(new Person[5] {})
;
3.1 shared_ptr的原理
-
一个
shared_ptr
会对一个对象产生强引用(strong reference
); -
每个对象都有个与之对应的强引用计数,记录着当前对象被多少个
shared_ptr
强引用着;- 可以通过
shared_ptr
的use_count
函数获得强引用计数;
- 可以通过
-
当有一个新的
shared_ptr
指向对象时,对象的强引用计数就会+1; -
当有一个
shared_ptr
销毁时(比如作用域结束),对象的强引用计数就会-1; -
当一个对象的强引用计数为0时(没有任何
shared_ptr
指向对象时),对象就会自动销毁(析构)。
3. 2 实例
Person *p = new Person(); // Person()
{
shared_ptr<Person> p1(p);
} // ~Person()
{
shared_ptr<Person> p2(p);
} // ~Person()
3.3 shared_ptr的循环引用
4. weak_ptr
weak_ptr
会对一个对象产生弱引用;weak_ptr
可以指向对象解决shared_ptr
的循环引用问题。
class Car {
public:
weak_ptr<Person> m_person;
};
class Person {
public:
share_ptr<Car> m_car = nullptr;
};
share_ptr<Person> person(new Person());
share_ptr<Car> car(new Car());
person->m_car = car;
car->m_person = person;
4.1 weak_ptr解决循环引用
5. unique_ptr
unique_ptr
也会对一个对象产生强引用,它可以确保同一时间只有1个指针指向对象;- 当``unique_ptr`销毁时(作用域结束时),其指向的对象也就自动销毁了;
- 可以使用
std::move
函数转移unique_ptr
的所有权;
// ptr1强引用着Person对象
unique_ptr<Person> ptr1(new Person());
// 转移之后,ptr1强引用着Person对象
unique_ptr<Person> ptr2 = std::move(ptr1);