本文代码来自陈硕《Linux 多线程服务端编程:使用 muduo C++ 网络库》
观察者模式的目的是让博客更新之后,所有订阅了博客的人都能得到通知
这里使用了智能指针来实现,从而完整的解决了资源管理的问题。
实现效果:
源代码:
Blog.h
#pragma once
#include <string>
#include <iostream>
using namespace std;
#include <vector>
#include "boost/weak_ptr.hpp"
//#include "Observer.h"这里不能包含头文件,会循环引用
class Observer;//这里只能使用前置声明
class Blog
{
public:
Blog()
{
cout<<"Blog()"<<endl;
}
~Blog(void);
void set_name(const string& name)
{
name_ = name;
}
const string get_name()
{
return name_;
}
void set_status(const string& s)
{
status_ = s;
}
const string get_status(void) const
{
return this->status_;
}
void add_observer(const boost::shared_ptr<Observer>& pobserver)
{
observers_.push_back(pobserver);
}
void notify(void);
private:
string name_;
string status_;
//这里使用weak_ptr是仅仅引用资源,而不产生使用计数,防止循环引用而不能析构
vector<boost::weak_ptr<Observer> > observers_;
typedef vector<boost::weak_ptr<Observer> >::iterator iter;
};
Blog.cpp
#include "Blog.h"
#include "Observer.h"//在这里包含头文件
Blog::~Blog(void)
{
cout<<"~Blog()"<<endl;
}
void Blog::notify(void)
{
iter i = observers_.begin();
//标准写法
while(i!=observers_.end())
{
//weak_ptr本身不具备访问能力(单一职责),都是通过shared_ptr来实现
boost::shared_ptr<Observer> pobserver(i->lock());
//判断对象是否已经析构
if (pobserver)
{
pobserver->update();
//迭代器在这里前进
++i;
}
//已经析构的对象不再引用
else
{
i = observers_.erase(i);
}
}
}
Observer.h
#pragma once
#include <string>
#include <iostream>
using namespace std;
#include "Blog.h"
#include "boost/shared_ptr.hpp"
#include "boost/weak_ptr.hpp"
class Observer
{
public:
//由于只能指针都是值语义的,所以使用常值引用可以减少复制
Observer(const string& name,const boost::shared_ptr<Blog>& pblog)
:name_(name),blog_(pblog)
{
cout<<"Observer("<<name_<<")订阅了"<<blog_.lock()->get_name()<<endl;
}
~Observer(void)
{
cout<<"~Observer("<<name_<<")"<<endl;
}
void update(void)
{
cout<<name_<<"知道了"
<<blog_.lock()->get_name()
<<blog_.lock()->get_status()<<endl;
}
private:
string name_;
//这里使用weak_ptr是仅仅引用资源,而不产生使用计数,防止循环引用而不能析构
boost::weak_ptr<Blog> blog_;
};
observer_main.cpp
#include "Blog.h"
#include "Observer.h"
#include "boost/shared_ptr.hpp"
int main()
{
boost::shared_ptr<Blog> pblog(new Blog());
pblog->set_name("CalmReason CSDN Blog");
boost::shared_ptr<Observer> pobserver1(new Observer("张三",pblog));
boost::shared_ptr<Observer> pobserver2(new Observer("李四",pblog));
pblog->add_observer(pobserver1);
pblog->add_observer(pobserver2);
pblog->set_status("发表了博客:C++的内存管理");
pblog->notify();
pblog->set_status("发表了博客:weak_ptr的基本用法");
pblog->notify();
return 0;
}