zoukankan      html  css  js  c++  java
  • C++11:智能指针与lambda表达式

    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行改成了按引用捕获,执行结果:

     

  • 相关阅读:
    名词解释字节码
    一次Java解析数独的经历
    Java运行时数据区域
    java中的泛型类和泛型方法
    兼容的一些问题
    js中变量的作用域
    CSS3渐变
    Extjs散记
    Linux系统CentOS下mysql的安装日志
    修改自动亮度下背光和按键的亮度
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/13431987.html
Copyright © 2011-2022 走看看