最常見的程序員面試題(12)觀察者模式和weak_ptr

觀察者模式是非常常用的,寫出松耦合框架代碼的設計模式。常見的問題是:

(1) 如何實現一些列的觀察者? A: 用一個EventManager來註冊和反註冊。

(2) 對於被觀察者,如何做到通知觀察者一個對象已經沒有了? 第一種方法是在被觀察者對象的析構函數中調用Unregister。這樣可以工作,但是問題是需要修改"被觀察者"的析構函數代碼,破壞了"觀察者"這個語義的封裝性,使得被觀察者和設計模式之間變得耦合。鬆綁的方法是採用std::weak_ptr來做觀察者,對象的創建採用std::shared_ptr。例子代碼如下: 一個vector<int>是被觀察對象,當刪除了頭尾兩個元素的時候,觀察者不需要特地的"被通知",因爲此時share_ptr的use_count已經清0。打印的就是清空後的結果。因爲weak_ptr就是shared_ptr的觀察者。VC2010和GCC4.7測試通過。

  1. #include <vector>   
  2. #include <memory>   
  3. using namespace std;  
  4. int main(){   
  5.     typedef shared_ptr<int> sp_int;  
  6.     vector<sp_int> vi;  
  7.     vi.push_back(sp_int(new int(1)));  
  8.     vi.push_back(sp_int(new int(2)));  
  9.     vi.push_back(sp_int(new int(3)));  
  10.   
  11.     typedef weak_ptr<int> wp_int;  
  12.     vector<wp_int> wi;  
  13.     for( auto it = vi.begin(); it != vi.end(); ++ it ){  
  14.         wi.push_back( wp_int( *it ) );  
  15.     }  
  16.   
  17.     vi.erase( vi.begin() );  
  18.     vi.pop_back();  
  19.     for( auto it = wi.begin(); it != wi.end(); ++ it ){  
  20.         if( it->use_count() ){  
  21.             cout<<*( it->lock().get() );  
  22.         }  
  23.     }  
  24.     return 0;  
  25. }  
#include <vector>
#include <memory>
using namespace std;
int main(){ 
    typedef shared_ptr<int> sp_int;
    vector<sp_int> vi;
    vi.push_back(sp_int(new int(1)));
    vi.push_back(sp_int(new int(2)));
    vi.push_back(sp_int(new int(3)));

    typedef weak_ptr<int> wp_int;
    vector<wp_int> wi;
    for( auto it = vi.begin(); it != vi.end(); ++ it ){
        wi.push_back( wp_int( *it ) );
    }

    vi.erase( vi.begin() );
    vi.pop_back();
    for( auto it = wi.begin(); it != wi.end(); ++ it ){
        if( it->use_count() ){
            cout<<*( it->lock().get() );
        }
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章