午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

智能指針

 黃建校 2015-11-21

智能指針就是存儲指向堆上分配的對象的指針,行為上與C++的原生指針基本一致,區(qū)別是不需要管理對象的銷毀。智能指針可以選擇在適當(dāng)?shù)臅r機(jī)銷毀對象,可以大幅降低空懸指針和野指針等錯誤。所有智能指針如果是非類成員,一般都是棧上分配的對象。這里介紹boost庫的智能指針,主要有:

1. scoped_ptr

概念上講,智能指針意味著持有它所指向?qū)ο蟮膿碛袡?quán),有責(zé)任在該對象不在需要時對其銷毀。scoped_ptr只提供了RAII機(jī)制,對它指向的對象具有唯一的擁有權(quán),不會被共享和轉(zhuǎn)移。這是通過不可拷貝實現(xiàn)的,所以scoped無法存放到stl容器中。指向的對象在scoped_ptr析構(gòu)或者reset后會被釋放。scoped_ptr實現(xiàn)很簡單,基本與原生指針性能差不多。scoped_ptr用在類成員時,可以避免在析構(gòu)函數(shù)中釋放指針。

  1. class A {  
  2. ...  
  3. private:  
  4.     B *obj;  
  5. };  
類A的析構(gòu)函數(shù)不得不對指針obj進(jìn)行delete操作,而改成scoped_ptr則可以避免:
  1. class A {  
  2. ...  
  3. private:  
  4.     boost::scoped_ptr<B> obj;  
  5. };  

2. shared_ptr

以引用計數(shù)的方式共享指針的擁有權(quán)。當(dāng)最后一個shared_ptr被銷毀時,指向的對象也會被銷毀。由于使用引用計數(shù),無法解決循環(huán)引用的問題。shared_ptr實現(xiàn)了拷貝構(gòu)造函數(shù)和賦值運(yùn)算符,可以存放到stl容器中。同時,也實現(xiàn)了比較運(yùn)算符,可以存放到關(guān)聯(lián)容器中。

如果T *可以隱式轉(zhuǎn)化(通過static_cast)為U *,那么shared_ptr<T>也可以隱式轉(zhuǎn)化為shared_ptr<U>。

線程安全反面,shared_ptr支持:a. 并發(fā)讀,b. 并發(fā)寫多個不同的實例,c. 不支持并發(fā)讀寫同一個實例(需加鎖)。

下列程序存在循環(huán)引用:

  1. #include <iostream>                                                                                                                               
  2.   
  3. #include <boost/shared_ptr.hpp>                                                                                                                   
  4. #include <boost/weak_ptr.hpp>                                                                                                                     
  5.   
  6. using namespace std;                                                                                                                              
  7. using namespace boost;                                                                                                                            
  8.       
  9. class B;                                                                                                                                          
  10.      
  11. class A {                                                                                                                                         
  12. public:                                                                                                                                           
  13.     ~A() {                                                                                                                                        
  14.         cout << "ref count of B: " << bptr.use_count() << endl;                                                                                   
  15.         cout << "deconstruct A" << endl;                                                                                                          
  16.     }                                                                                                                                             
  17.       
  18.     shared_ptr<B> bptr;                                                                                                                           
  19. };                                                                                                                                                
  20.   
  21. class B {                                                                                                                                         
  22. public:                                                                                                                                           
  23.     ~B() {                                                                                                                                        
  24.         cout << "ref count of A: " << aptr.use_count() << endl;                                                                                   
  25.         cout << "deconstruct B" << endl;                                                                                                          
  26.     }                                                                                                                                             
  27.   
  28.     shared_ptr<A> aptr;                                                                                                                         
  29. };                                                                                                                                                
  30.   
  31. void test()                                                                                                                                       
  32. {                                                                                                                                                 
  33.     cout << "begin" << endl;                                                                                                                      
  34.     shared_ptr<A> aptr(new A);                                                                                                                    
  35.     shared_ptr<B> bptr(new B);      
  36.       
  37.     aptr->bptr = bptr;     
  38.     bptr->aptr = aptr;                                                                                                                           
  39.   
  40.     cout << "ref count of bptr: " << bptr.use_count() << endl;                                                                                    
  41.     cout << "ref count of aptr: " << aptr.use_count() << endl;                                                                                   
  42.   
  43.     cout << "end" << endl;                                                                                                                        
  44. }                                                                                                                                                 
  45.   
  46. int main()                                                                                                                                        
  47. {                                                                                                                                                 
  48.     test();                                                                                                                                       
  49.     cout << "after test" << endl;                                                                                                                 
  50. }     

運(yùn)行程序,可以發(fā)現(xiàn)A和B都沒有被析構(gòu)。下面通過weak_ptr解決這種循環(huán)引用的問題。

  1. begin  
  2. ref count of bptr: 2  
  3. ref count of aptr: 2  
  4. end  
  5. after test  

3. weak_ptr

weak_ptr不管理對象的生命周期,但是可以感知一個對象的生死。weak_ptr是弱引用,用它指向一個對象,不會增加其引用計數(shù)。weak_ptr指向的對象底層有shared_ptr管理,要通過weak_ptr訪問這個對象,必須構(gòu)造成shread_ptr才行。具體可以通過shared_ptr的構(gòu)造函數(shù)或者是lock方法。當(dāng)最后一個指向該對象的shared_ptr被銷毀時,該對象也會被銷毀。此時,調(diào)用shared_ptr的構(gòu)造函數(shù)會拋出boost::bad_weak_ptr異常,lock返回的shared_ptr是空的。

weak_ptr實現(xiàn)了拷貝構(gòu)造函數(shù)、賦值運(yùn)算符和比較運(yùn)算符所以可以放入stl容器和關(guān)聯(lián)容器中。

下面看一下,weak_ptr是如何解決循環(huán)引用,將類B中指向aptr的shared_ptr改為weak_ptr即可。

  1. #include <iostream>                                                                                                                               
  2.                                                                                                                                                   
  3. #include <boost/shared_ptr.hpp>                                                                                                                   
  4. #include <boost/weak_ptr.hpp>                                                                                                                     
  5.                                                                                                                                                   
  6.                                                                                                                                                   
  7. using namespace std;                                                                                                                              
  8. using namespace boost;                                                                                                                            
  9.                                                                                                                                                   
  10. class B;                                                                                                                                          
  11.                                                                                                                                                   
  12. class A {                                                                                                                                         
  13. public:                                                                                                                                           
  14.     ~A() {                                                                                                                                        
  15.         cout << "ref count of B: " << bptr.use_count() << endl;                                                                                   
  16.         cout << "deconstruct A" << endl;                                                                                                          
  17.     }                                                                                                                                             
  18.                                                                                                                                                   
  19.     shared_ptr<B> bptr;                                                                                                                           
  20. };                                                                                                                                                
  21.                                                                                                                                                   
  22. class B {                                                                                                                                         
  23. public:                                                                                                                                           
  24.     ~B() {                                                                                                                                        
  25.         cout << "ref count of A: " << aptr.use_count() << endl;                                                                                   
  26.         cout << "deconstruct B" << endl;                                                                                                          
  27.     }                                                                                                                                                                                                                                                              
  28.     weak_ptr<A> aptr;                                                                                                                             
  29. };                                                                                                                                                
  30.                                                                                                                                                   
  31. void test()                                                                                                                                       
  32. {                                                                                                                                                 
  33.     cout << "begin" << endl;                                                                                                                      
  34.     shared_ptr<A> aptr(new A);                                                                                                                    
  35.     shared_ptr<B> bptr(new B);                                                                                                                    
  36.                                                                                                                                                   
  37.     weak_ptr<A> waptr(aptr);                                                                                                                      
  38.                                                                                                                                                   
  39.     aptr->bptr = bptr;                                                                                                                            
  40.     bptr->aptr = waptr;                                                                                                                           
  41.                                                                                                                                                   
  42.     cout << "ref count of bptr: " << bptr.use_count() << endl;                                                                                    
  43.     cout << "ref count of aptr: " << waptr.use_count() << endl;                                                                                   
  44.                                                                                                                                                   
  45.     cout << "end" << endl;                                                                                                                        
  46. }                                                                                                                                                 
  47.                                                                                                                                                   
  48. int main()                                                                                                                                        
  49. {                                                                                                                                                 
  50.     test();                                                                                                                                       
  51.     cout << "after test" << endl;                                                                                                                 
  52. }     
運(yùn)行結(jié)果:

  1. begin  
  2. ref count of bptr: 2  
  3. ref count of aptr: 1  
  4. end  
  5. ref count of B: 1  
  6. deconstruct A  
  7. ref count of A: 0  
  8. deconstruct B  
  9. after test  
可以看到A和B都被析構(gòu)了,并且在test函數(shù)的結(jié)尾處,檢查aptr的引用計數(shù)是1,而bptr是2,這是因為weak_ptr指向這個對象,不會引起引用計數(shù)的改變。





    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多