首页 > 技术文章 > C++11:智能指针与lambda表达式

wanmeishenghuo 2020-08-04 11:04 原文

c++11中的智能指针的引用计数什么时候增加?什么时候减少?

测试程序

 1 #include <iostream>
 2 #include <memory>
 3 #include <functional>
 4 
 5 using f_callback1 = std::function<void()>; 
 6 
 7 f_callback1 f1;
 8 
 9 void set_f_callback1(f_callback1 f)
10 {
11     f();
12     f1 = f;
13     f1();
14 }
15 
16 class student : public  std::enable_shared_from_this<student>
17 {
18     public:
19         student(int age) { age_ = age;}
20     
21     int test_count()
22     {
23         auto self = this->shared_from_this();
24         
25         set_f_callback1([self](){ 
26                         std::cout << "from student, count : " <<  self.use_count() << std::endl;
27                         
28                 });
29 
30         return self.use_count();    
31     }    
32     
33     private:
34         int age_;
35 };
36 
37 
38 
39 int  main()
40 {
41     std::shared_ptr<student> ptr1 = std::make_shared<student>(20);
42 
43     std::cout << "test count1 : " << ptr1->test_count() << std::endl;
44 
45     std::cout << "test count2 : " << ptr1.use_count() << std::endl;
46 
47     f1();
48 
49     return 0;
50 }

执行结果如下:

第25行将一个lambda设置到全局变量f1上,f1是一个function函数对象。 self这种方式是值捕获。 因为self是局部对象,声明周期无法保证,不能用引用捕获。

进入到第9行的set_f_callback1函数之后调用f,这时真正的student对象的引用计数是3。分别为41行的ptr1、23行的self、25行的lambda表达式中的self。

进入到第13行进行调用时引用计数是 4,因为这时候f赋值给了f1. 因为函数对象里面有self这个shared ptr的拷贝,所以赋值给f1的时候又拷贝了一份,所以引用计数为4。

第30行的代码返回的是3,这时候分别为41行的ptr1、23行的self、f1这个函数对象里面保存的self的拷贝。 这个时候f这个拷贝已经离开作用域释放了。

第45行打印结果为2,这时候分别为41行的ptr1、f1这个函数对象里面保存的self的拷贝。 23行的self已经离开作用域释放了。

第47行打印结果为2,这时候分别为41行的ptr1、f1这个函数对象里面保存的self的拷贝。

 

下面给出错误的使用方式,引用捕获,我们主要还是关注引用计数的变化,不关注崩溃。

 1 #include <iostream>
 2 #include <memory>
 3 #include <functional>
 4 
 5 using f_callback1 = std::function<void()>; 
 6 
 7 f_callback1 f1;
 8 
 9 void set_f_callback1(f_callback1 f)
10 {
11     f();
12     f1 = f;
13     f1();
14 }
15 
16 class student : public  std::enable_shared_from_this<student>
17 {
18     public:
19         student(int age) { age_ = age;}
20     
21     int test_count()
22     {
23         auto self = this->shared_from_this();
24         
25         set_f_callback1([&self](){ 
26                         std::cout << "from student, count : " <<  self.use_count() << std::endl;
27                         
28                 });
29 
30         return self.use_count();    
31     }    
32     
33     private:
34         int age_;
35 };
36 
37 
38 
39 int  main()
40 {
41     std::shared_ptr<student> ptr1 = std::make_shared<student>(20);
42 
43     std::cout << "test count1 : " << ptr1->test_count() << std::endl;
44 
45     std::cout << "test count2 : " << ptr1.use_count() << std::endl;
46 
47     f1();
48 
49     return 0;
50 }

第25行改成了按引用捕获,执行结果:

 

 

 

 

推荐阅读