智能指针 reset weakptr

简介: 智能指针 reset weakptr

智能指针reset()方法分析

reset()函数接受一个可选参数,这个参数可以是一个指向新对象的指针,也可以是一个空指针。

当参数为空指针时,reset()会释放原来指针所管理的资源,同时将指针置为空。当参数为非空指针时,

reset()会先释放原来指针所管理的资源,然后将指针重新指向新对象,

此时此刻,如果有其它智能指针也指向它,只是计数减一。

当使用reset函数时,智能指针的引用计数会相应地减少1。如果减少后引用计数变为0,则表示该资源不再被使用,可以安全地删除资源。

可以通过下面的代码去调试理解:

#include <iostream>
#include <functional>
#include <memory>
#include <thread>
class A{
    public:
    A(int x) : _x(x){
        std::cout << " create " << _x << std::endl;
    }
    ~A(){
        std::cout << " release " << _x << std::endl;
    }
    int _x;
};

void testshared_ptr_Reset(){
    std::shared_ptr<A> p(new A(1));  // 这里create A(1)
    std::cout << p.use_count() << "   p.get() = " << p.get() << __LINE__ << std::endl;

    std::cout << p.get() << "   " << __LINE__ << std::endl;
    auto p2 = p;
    auto p21 = p;
    std::cout << p.use_count() << "   " << __LINE__ << std::endl;

    p.reset();
    p.reset();
    p.reset(); //多次reset,A(1)的引用次数只减少了1,

    std::cout << p2.use_count() << "   << p2.get() = " << p2.get() << __LINE__ << std::endl;  // p2.get() == p1.get()
    auto p3 = p;
    std::cout << p.use_count() << "   " << __LINE__ << std::endl;
    std::cout << p3.use_count() << "   " << __LINE__ << std::endl;
    auto p4 = p;
    std::cout << p.use_count() << "   " << __LINE__ << std::endl;

    p.reset(new A(2)); // 这里create A2
    std::cout << p.use_count() << "   " << __LINE__ << std::endl;
    std::cout << p3.use_count() << "   " << __LINE__ << std::endl;

    // 退出的时候释放两次实例 A2 A1
}

智能指针循环引用

这是不推荐的,不要同时你中有我,我中有你,即:A的成员智能指针指向B,B的成员智能指针指向A

相互持有的时候,两边的析构函数都没有被调用到,造成内存泄漏。

这时候可以同weak_ptr来解决,它指向智能指针sp,但是并不持有引用计数,即sp的use_count()不会增加。

weak_ptr用法

接续前面的代码,weak_ptr的 lock, expired, use_count 三个函数了解它

weak_ptr调试的代码

std::weak_ptr<A> gw;
void TestWeakPtr(){
    gw.lock();
    std::this_thread::sleep_for(std::chrono::seconds(5));
    if(gw.expired()){
        std::cout << "wb lock gp success !" << std::endl;    
    } else {
        std::cout << "wb lock gp failed !" << std::endl;    
    }
}
int main(){
    std::shared_ptr<A> sp(new A(3));
    gw = sp;
    std::cout << " gw.use_count() = " << gw.use_count() << " sp.use_count() = " << sp.use_count() << std::endl;
    std::thread ([&](){
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << " sp reset \n";
        sp.reset();
    }).detach();

    TestWeakPtr(); // 测试A(3)的资源使用情况
    std::cout << " gw.use_count() = " << gw.use_count() << " sp.use_count() = " << sp.use_count() << std::endl;
    return 0;
}

输出:

create 3
gw.use_count() = 1 sp.use_count() = 1 //增加了gw对sp的应用,但是sp的use_count()没有增加
sp reset
release 3
wb lock gp success !
gw.use_count() = 0 sp.use_count() = 0

相关文章
|
6月前
|
安全 程序员 编译器
C++中的RAII(资源获取即初始化)与智能指针
C++中的RAII(资源获取即初始化)与智能指针
79 0
|
6月前
|
安全 程序员 C++
C++中的智能指针:从原始指针到现代内存管理
C++中的智能指针:从原始指针到现代内存管理
48 0
|
6月前
|
C++
C++:一文读懂智能指针
C++:一文读懂智能指针
95 0
|
6月前
|
消息中间件 Kubernetes NoSQL
智能指针的种类以及使用场景
智能指针的种类以及使用场景
|
6月前
|
安全 C++
c++11新特性——智能指针详解
c++11新特性——智能指针详解
|
6月前
|
安全 C++ 容器
C++中的智能指针:自动内存管理的利器
C++中的智能指针:自动内存管理的利器
79 0
|
6月前
|
设计模式 Rust Java
【一起学Rust | 设计模式】习惯语法——默认特质、集合智能指针、析构函数
【一起学Rust | 设计模式】习惯语法——默认特质、集合智能指针、析构函数
95 0
|
6月前
|
存储 Rust C++
C++智能指针
【2月更文挑战第14天】介绍C++智能指针
49 0
|
6月前
|
算法 安全 C++
C++ Effective Modern Pointer (智能指针模块)
C++ Effective Modern Pointer (智能指针模块)