![f11b1035ee47d2a6bbd1a070af374a95.png](https://i-blog.csdnimg.cn/blog_migrate/87e3aabfc7cb43f3849f149a2601a60d.jpeg)
本文是本书最后一篇文章,完结撒花!谢谢大家观看!
目录:
trick:Hands-On Design Patterns With C++(零)前言zhuanlan.zhihu.com![d24ba7ef94fb94b4dd1d22b58962ed94.png](https://i-blog.csdnimg.cn/blog_migrate/f7c81ce14fb52d532499952b8439f62b.jpeg)
访问者模式与多分派(下)
本文概要:
(1)编译期的访问者模式
(2)访问者模式与组合模式融合
PS:本文代码地址:https://github.com/PacktPublishing/Hands-On-Design-Patterns-with-CPP/tree/master/Chapter18
编译期访问者模式
本节我们讨论在编译时使用访问者模式的可能性。首先,模板使访问者模式实现多重调度很方便:
template <typename T1, typename T2> auto f(T1 t1, T2 t2);
模板函数可以轻松地针对T1和T2类型的任何组合运行不同的算法。 与虚函数实现的运行期多态不同,两种或多种类型组合调度不会产生额外的性能开销(当然,除了编写我们需要处理的所有组合的代码外)。 由此我们可以在编译期使用经典的访问者模式:
class Pet {
std::string color_;
public:
Pet(const std::string& color) : color_(color) {}
const std::string& color() const {
return color_; }
template <typename Visitable, typename Visitor>
static void accept(Visitable& p, Visitor& v) {
v.visit(p); } // accept此时非虚
};
accept()
此时是一个模板函数,同时也是静态成员函数,其第一个参数(Visitable& p
)的实际类型是Pet派生类对象,它将在编译时推导出。 具体的可访问类是从基类派生的:
class Cat : public Pet {
public:
using Pet::Pet;
};
class Dog : public Pet {
public:
using Pet::Pet;
};
访问者(Visitor
)不需要继承于公共基类,因为我们会在编译时解析类型: