(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測試通過。
- #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;
- }
#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;
}