本次讲c++11改进我们的模式之改进访问者模式
访问者模式是GOF23个设计模式中比较复杂的模式之一,但是它的功能也很强大,非常适合稳定的继承层次中对象的访问,可以在不修改被访问对象的情况下,动态添加职责,这正是访问者模式强大的地方,但是它的实现又造成了两个继承层次的强烈耦合,这也是被人诟病的地方,可以说是让人爱又让人恨的模式。c++11实现的访问者模式将会解决这个问题。我们将在c++11版本的访问者模式中看到,定义新的访问者是很容易的,扩展性很好,被访问者的继承层次也不用做任何修改。具体代码:
template<typename... Types> struct Visitor; template<typename T, typename... Types> struct Visitor<T, Types...> : Visitor<Types...> { using Visitor<Types...>::Visit; virtual void Visit(const T&) = 0; }; template<typename T> struct Visitor<T> { virtual void Visit(const T&) = 0; };
上面的代码为每个类型都定义了一个纯虚函数Visit。
下面看看被访问的继承体系如何使用Visitor访问该继承体系的对象。
struct stA; struct stB; struct Base { typedef Visitor<stA, stB> MytVisitor; virtual void Accept(MytVisitor&) = 0; }; struct stA: Base { double val; void Accept(Base::MytVisitor& v) { v.Visit(*this); } }; struct stB: Base { int val; void Accept(Base::MytVisitor& v) { v.Visit(*this); } }; struct PrintVisitor: Base::MytVisitor { void Visit(const stA& a) { std::cout << "from stA: " << a.val << std::endl; } void Visit(const stB& b) { std::cout << "from stB: " << b.val << std::endl; } };
测试代码:
void TestVisitor() { PrintVisitor vis; stA a; a.val = 8.97; stB b; b.val = 8; Base* base = &a; base->Accept(vis); base = &b; base->Accept(vis); }
测试结果:
from stA: 8.97 from stB: 8
c++11 boost技术交流群:296561497,欢迎大家来交流技术。