Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value
*/-->
div.org-src-container {
font-size: 85%;
font-family: monospace;
}
pre.src {
background-color:#f8f4d7
}
p {font-size: 15px}
li {font-size: 15px}
严格来讲, C 和 C++ 都不支持将函数作为参数,真正作为参数的,实际上是
pass-by-value 的函数指针, 作为函数指针的模拟, Functor 作为参数时候也是按值传递的,有些 STL 的实现中,将 Functor 作为引用传递甚至不能通过编译。这也就要求我们将 Functor 设计得当,以满足传值:
- Functor 应该尽量小:
否则的话, Functor 的拷贝将会变得昂贵。 - Functor 应该为单态 (monomorphic): —— 不用使用虚函数
如果算法需要的是基类 Functor,但传入的是子类的话,拷贝过程中可能会引起 切片问题 。
但,离开了多态与继承的 C++ ,也就失去了后面的 ++, 变成了 C 。这里有一个办法可以将庞大的多态 Functor 分解成符合需求的 Functor,即将数据以及多态的部分封装成单独的类,然后在 Functor 中存储该类的指针,换句话说: Bridge Mode。
例如下面的这个 BPFC (Big Polymoriphic Functor Class):
template <typename T>
class BPFC : public unary_functor<T, void>()
{
public:
// XXX: This is virtual function, may cause slicing issue.
virtual void operator()(const T& val) const; private:
Widget w;
int x;
};
我们可以将其中的数据和多态部分拆分,形成下面的 Functor:
template <typename T>
class BPFCImpl
{
public:
virtual void operator(const T& val) const;
virtual ~BPFCImpl();
private:
Widget w;
int x;
}; template <typename T>
class BPFC : public unary_functor<T,void>
{
public:
void operator()(const T& val) const
{
pImpl->operator(val); // forward it to BPFCImpl
}
private:
BPFCImpl<T>* pImpl;
};
切记: Make functors small and monomorphic!
(转载请注明出处,使用许可:署名-非商业性使用-相同方式共享 3.0 *许可协议 。)