shared_ptr的 reset用法

 

 

复制代码
#include <iostream>
#include <future>
#include <thread>

using namespace std;
class Person
{
public:
    Person(int v) {
        value = v;
        std::cout << "Cons" <<value<< std::endl;
    }
    ~Person() {
        std::cout << "Des" <<value<< std::endl;
    }

    int value;

};

int main()
{
    std::shared_ptr<Person> p1(new Person(1));// Person(1)的引用计数为1

    std::shared_ptr<Person> p2 = std::make_shared<Person>(2);

    p1.reset(new Person(3));// 首先生成新对象,然后引用计数减1,引用计数为0,故析构Person(1)
                            // 最后将新对象的指针交给智能指针

    std::shared_ptr<Person> p3 = p1;//现在p1和p3同时指向Person(3),Person(3)的引用计数为2

    p1.reset();//Person(3)的引用计数为1
    p3.reset();//Person(3)的引用计数为0,析构Person(3)
    return 0;
}
复制代码

 

 

 

root@ubuntu:~/c++# ./reset
Cons1
Cons2
Cons3
Des1
Des3
Des2

 

 

注意,不能将一个原始指针直接赋值给一个智能指针,如下所示,原因是一个是类,一个是指针。

    std::shared_ptr<int> p4 = new int(1);// error

  reset()包含两个操作。当智能指针中有值的时候,调用reset()会使引用计数减1.当调用reset(new xxx())重新赋值时,智能指针首先是生成新对象,然后将就对象的引用计数减1(当然,如果发现引用计数为0时,则析构旧对象),然后将新对象的指针交给智能指针保管。

  • 获取原始指针  
    std::shared_ptr<int> p4(new int(5));
    int *pInt = p4.get();

 

 

复制代码
#include <iostream>
#include <future>
#include <thread>

using namespace std;
class Person
{
public:
    Person(int v) {
        value = v;
        std::cout << "Cons" <<value<< std::endl;
    }
    ~Person() {
        std::cout << "Des" <<value<< std::endl;
    }

    int value;

};

int main()
{
    std::shared_ptr<Person> p1(new Person(1));// Person(1)的引用计数为1

    std::shared_ptr<Person> p2 = std::make_shared<Person>(2);

    p1.reset(new Person(3));// 首先生成新对象,然后引用计数减1,引用计数为0,故析构Person(1)
                            // 最后将新对象的指针交给智能指针

    std::shared_ptr<Person> p3 = p1;//现在p1和p3同时指向Person(3),Person(3)的引用计数为2

    p1.reset();//Person(3)的引用计数为1
    p3.reset();//Person(3)的引用计数为0,析构Person(3)
    p3.reset();//再reset
    return 0;
}
复制代码

 

复制代码

root@ubuntu:~/c++# g++ -std=c++11 reset2.cpp -o reset2
root@ubuntu:~/c++# ./reset2
Cons1
Cons2
Cons3
Des1
Des3
Des2

复制代码

 

删除器 lambda

复制代码
#include <iostream>
#include <memory>
using  namespace  std;
class obj
{
private:
     int _num;
public:
   obj(int num):_num(num) { cout << "obj is constructed and num : " << num << endl; }
   ~obj() { cout << "obj is deleted and num " <<  _num << endl; }
};
void share_ptr()
{
     std::shared_ptr<obj> shared_ptr1(new obj(99));
     obj * p = shared_ptr1.get();
     cout << " addr "  <<  (long)p << endl;
     shared_ptr1.reset(new obj(33), [](obj* p1){ cout<<"in reset"  << " addr " <<  (long)p1  <<endl;  delete p1; });

     //p = shared_ptr1.get();
     //cout << " addr " <<hex << (long)p  <endl;     
}
int main()
{
   share_ptr();
   return 0;
}
复制代码

 

复制代码
oot@ubuntu:~/c++#  g++ -std=c++11  share2.cpp -o share2
root@ubuntu:~/c++# ./share2
obj is constructed and num : 99
 addr 187651489353328
obj is constructed and num : 33
obj is deleted and num 99
in reset addr 187651489354432
---------------------------- 先delete 99 后reset
obj is deleted and num 33
复制代码

 

 

复制代码
#include <iostream>
#include <memory>
using  namespace  std;
class obj
{
private:
     int _num;
public:
   obj(int num):_num(num) { cout << "obj is constructed and num : " << num << endl; }
   ~obj() { cout << "obj is deleted and num " <<  _num << endl; }
};
void share_ptr()
{
     std::shared_ptr<obj> shared_ptr1(new obj(99));
     obj * p = shared_ptr1.get();
     cout << " addr "  <<  (long)p << endl;
     shared_ptr1.reset(new obj(33), [](obj* p1){ cout<<"in reset"  << " addr " <<  (long)p1  <<endl;  });

     p = shared_ptr1.get();
     cout << " addr " << (long)p  << endl;
}
int main()
{
   share_ptr();
   return 0;
}
复制代码

 

复制代码
root@ubuntu:~/c++#  g++ -std=c++11  share2.cpp -o share2
root@ubuntu:~/c++# ./share2
obj is constructed and num : 99
 addr 187651132960368
obj is constructed and num : 33
obj is deleted and num 99   ---自动调用析构
 addr 187651132961472
in reset addr 187651132961472
root@ubuntu:~/c++# 
复制代码

 

posted on   tycoon3  阅读(20744)  评论(0编辑  收藏  举报

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示