#ifndef TEST_OBSERVER_SAFE
#define TEST_OBSERVER_SAFE
#include <stdio.h>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_guard.hpp>
namespace TestObserver
{
class Observable;
class Observer : public boost::enable_shared_from_this<Observer>
{
public:
Observer() {}
virtual ~Observer() {printf("%p is destructed!\n", this);}
virtual void update() = 0;
void observe(Observable* vSub);
protected:
Observable* m_Suject;
};
class Observable
{
public:
Observable() {}
~Observable() {printf("Observable is destructed!\n");}
void registerd(boost::weak_ptr<Observer> vObserver)
{
m_Observers.push_back(vObserver);
}
void notifyObservers()
{
boost::lock_guard<boost::mutex> Lock(m_Mutex);
for (Iterator it = m_Observers.begin(); it != m_Observers.end(); /*++it陷阱*/)
{
boost::shared_ptr<Observer> tmpObs(it->lock());
if (tmpObs)
{
tmpObs->update();
++it;
}
else
{
printf("notifyObervers erase()\n");
it = m_Observers.erase(it);
}
}
}
private:
boost::mutex m_Mutex;
std::vector<boost::weak_ptr<Observer>> m_Observers;
typedef std::vector<boost::weak_ptr<Observer>>::iterator Iterator;
};
void Observer::observe(Observable* vSub)
{
vSub->registerd(shared_from_this());
m_Suject = vSub;
}
class Foo : public Observer
{
public:
virtual void update()
{
printf("Foo::update() %p\n", this);
}
};
void fun_1()
{
flg_str("TestObserver::fun_1()");
Observable subject;
{
boost::shared_ptr<Foo> p(new Foo);
p->observe(&subject);
subject.notifyObservers();
}
subject.notifyObservers();
}
}
#endif