c++ 智能指针初步用法 unique_ptr/shared_ptr/weak_ptr
auto_ptr浅拷贝,带来很多问题,已经废弃
1. unique_ptr:内存的所有者或者说管理者必须是唯一的,如进入不同的模块或者调用者,那么执行所有权转移,通过release释放。
Student* p = new Student("lily");
std::unique_ptr<Student> unique_p(p);
unique_p.release(); // 使得unique_p释放控制器,下一步才可将p的控制权交给unque_p2
std::unique_ptr<Student> unque_p2(p); // 否则会
std::unique_ptr<Student> unque_p2(unique_p); // 错误,不能拷贝构造,因为函数已经删除

std::unique_ptr<Student> unque_p2(std::move(unique_p)); // 移动构造可以,让unique_p为空
2. shared_ptr: 内存由多个指针变量共同使用,共同拥有内存的所有权,但是必须杜绝循环拷贝!并且 shared_ptr 需要维护的信息有两部分:指向共享资源的指针;引用计数等共享资源的控制信息——维护一个指向控制信息的指针。
Student a;
std::shared_ptr<Student> ptra = std::make_shared<Student>(a);
std::shared_ptr<Student> ptra2(ptra); //拷贝构造函数
std::cout << ptra.use_count() << std::endl; //2
ptra2 = nullptr;
std::cout << ptra.use_count() << std::endl; //1
ptra = nullptr;
std::cout << ptra.use_count() << std::endl; //0
当引用计数为0的时候,则调用delete,释放资源:

3. weak_ptr: 对内存的使用仅仅是访问而已,不涉及其生命周期的管理,资源的释放只取决shared的计数,当计数为0时,释放资源,weak_ptr不控制资源的生命周期。
// 解决循环引用
{
std::shared_ptr<WeakNode> sp1(new WeakNode);
std::shared_ptr<WeakNode> sp2(new WeakNode);
sp1->next_ = sp2;
sp2->pre_ = sp1;
}
class WeakNode
{
public:
int data_;
std::shared_ptr<WeakNode> pre_;
std::shared_ptr<WeakNode> next_;
~WeakNode()
{
std::cout << "destruct..." << std::endl;
}
};

将成员pre_ 或 next_改为:weak_ptr类型即可:
class WeakNode
{
public:
int data_;
// 2个成员 一个改为 weak_ptr即可解决循环引用
std::weak_ptr<WeakNode> pre_;
std::shared_ptr<WeakNode> next_;
~WeakNode()
{
std::cout << "destruct..." << std::endl;
}
};
改造后,解决循环引用,可以释放:
