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行改成了按引用捕獲,執行結果:

