函数对象

函数对象:

通常我们可以将函数作为参数传入另一个参数,比如qsort中传递函数指针。
STL函数对象则是函数指针的一种抽象形式。


传递方式:

由于标准库函数中,函数指针的传递是按照值传递的;所以函数对象在函数之间的传递也是 值传递

for_each示例:

template<class InputIterator, class Function>
Function
for_each(InputIterator first, InputIterator last, Function f);//按值传递past-by-value

函数对象示例:

class Dosomething :public unary_function<int, void>{
public:
    void operator()(int x){};
};

int main()
{
    typedef vector<int>::iterator IntIterator;
    vector<int> di;
    Dosomething d;//创建一个函数对象
    //用类型参数dequeInerator和Dosomething&来调用for_each,这将强制d按照引用传递并返回
    for_each<IntIterator, Dosomething&>(di.begin(), di.end(), d);
    return 0;
}

合理设计:

因为函数对象是按照值传递的,所以需要注意一些问题:

  • 函数对象应该尽可能的小, 减小拷贝时的花销
  • 函数对象应该是单态的,否则值传递过程中会发生剥离(派生类对象 赋值到 基类对象上,仅仅保留基类部分)

但是没有继承的函数子类感觉很鸡肋
解决:
将函数子类中的 大量数据 和 多态放置到一个新的类中,然后函数对象中值保存新类的指针。
(通过新生类实现多态并减小了函数子类的负担)

template<typename T>
class BPFCImpl :public unary_function<T, void>{
private:
    float a;//原来BPFC中的数据
    int x;
    virtual ~BPFCImpl();//多态类需要虚析构函数
    virtual void operator()(const T& val)conat;
    friend class BPFC<T>;//允许BPFC访问内部数据
};
//通过BPFCImpl的多态实现函数对象的多态

template<typename T>
class BPFC :public unary_function<T, void>{
private:
    BPFCImpl<T> *pImpl;
public:
    void operator()(const T& val)const
    {
        pImpl->operator()(val);
    }
};

参考:

Effective STL

原文地址:https://www.cnblogs.com/Przz/p/6591049.html