1、错误示例
将仿函数类的数据和/或多态移到另一个类中,然后给你的仿函数一个指向这个新类的指针。比如,你想建立
一个包含很多数据的多态仿函数类。
这个技术在《Effective C++》的条款34中有。在Gamma等的《设计模式》中,这叫做“Bridge模式”。Sutter在他的《Exceptional C++》中叫它“Pimpl惯用法”。
将仿函数类的数据和/或多态移到另一个类中,然后给你的仿函数一个指向这个新类的指针。比如,你想建立
一个包含很多数据的多态仿函数类。
template<typename T>
class BPFC : public unary_function<T, void> { // BPFC = "Big Polymorphic Functor Class"
private:
Widget w; // 这个类有很多数据,所以用值传递会影响效率
int x;
...
public:
virtual void operator()(const T& val) const; // 这是一个虚函数,所以切割时会出问题
...
};
2、正确示例
建立一个包含指向实现类的指针的小而单态的类,然后把所有数据和虚函数放到实现类:
template<typename T> // 用于修改的BPFC的新实现类
class BPFCImpl : public unary_function<T, void> {
private:
Widget w; // 以前在BPFC里的所有数据现在在这里
int x;
...
virtual ~BPFCImpl(); // 多态类需要虚析构函数
virtual void operator()(const T& val) const;
friend class BPFC<T>; // 让BPFC可以访问这些数据
};
template<typename T>
class BPFC : public unary_function<T, void> { // 小的、单态版的BPFC
private:
BPFCImpl<T> *pImpl; // 这是BPFC唯一的数据
public:
void operator()(const T& val) const // 现在非虚
{
pImpl->operator()(val); // 调用BPFCImpl的
}
};
这个技术在《Effective C++》的条款34中有。在Gamma等的《设计模式》中,这叫做“Bridge模式”。Sutter在他的《Exceptional C++》中叫它“Pimpl惯用法”。