仿函数 (Functors,也叫函数子)

Posted on 2020-12-07 19:44  金色的省略号  阅读(324)  评论(0编辑  收藏  举报

  Functors,仿函数,其实就是重载了括号运算符 () 的  对象,也称为函数子,有参构造函数无参构造函数均可构造函数子

  函数子,可以具有函数的一些性质,可以拥有状态,可以在运行时动态地改变行为,可以在需要函数的地方 ( 主要是各种容器和算法 ) 使用;参数传值,仿函数的状态不会因算法而改变;参数传引用,仿函数的状态因算法而改变 

  对象用作函数1 ( 无参构造对象 )

#include <iostream>
using namespace std;

class Add{
public:
    int operator()(int a, int b)
    {
        return a + b;
    }
};

int main()
{
    Add add; // 构造对象, 无参构造
    cout << add(3,2); // 看起来像函数调用,其实是重载了 () 的对象,函数子
    return 0;
}

  对象用作函数2 ( 无参构造对象 )

#include<iostream>
#include <vector>
#include <algorithm>  //for_each 需要的头文件
using namespace std;

struct D {
    int num;
    D(int i=0) {num = i; }
};

struct print_D{     //重载了() 运算符的结构体 
    void operator()(const D* d)const{
        cout << "I am D. my num=" << d->num << endl;
    }
};

void print(const D* d){  //函数   
    cout << "I am D. my num=" << d->num << endl;
};

int main()
{
    vector<D*> V;
    V.push_back(new D(1));
    V.push_back(new D(2));
    V.push_back(new D);
    V.push_back(new D(3));
    
    cout << "1.--------------" << endl;
    for_each( V.begin(), V.end(), print_D() );  // print_D()是struct print_D 的无名对象
    
    cout << "2.--------------" << endl;
    for_each( V.begin(), V.end(), print ); // 效果同上
    
    cout << "3.--------------" << endl;
    print_D d1;  
    d1( new D(121) ); // 对象d1重载(), 参数是 struct D的指针
    
    cout << "4.--------------" << endl;
    print_D()( new D(789) );  // 无名对象 print_D()
    
    return 0;
}

  对象用作函数3 ( 有参构造对象 )

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

struct Play
{
    const char* str;
    Play(const char* s):str(s) {}  //有参构造函数
    void operator () (int i)
    {
        cout << str << i << endl;
    }
};

int main()
{
    int a[] = { 1, 3, 4, 5};
    vector<int> vc( a, a+sizeof(a)/sizeof(int) );
    for_each( vc.begin(), vc.end(), Play("Element:") ); 
    return 0;
}

  对象用作函数4 ( 有参构造对象 )

#include <iostream>
using namespace std;

class Add{
    const char* str;  
public:
    Add() { }
    Add(const char* s):str(s) {  }  //有参构造
    void operator()(int a, int b, int c=0)
    {
        cout << str << a + b + c << endl;
    }
};

int main()
{
    Add add("相加的和:"); // 构造对象, 有参构造
    add(3,2);
    add(4,5,6);
    return 0;
}

  类模板 ( 创建模板类对象 )

  类模板与模板类( class  template, template class );类模板的重点是模板,表示的是一个模板,专门用于产生类的模子;模板类的重点是类,表示的是由一个模板生成而来的类

#include <iostream>
using namespace std;

template <class T> 
class Add{
    const char* str;  
public:
    Add() { }
    Add(const char* s):str(s) {  }  //有参构造
    void operator()(T a, T b, T c=0)
    {
        cout << str << a + b + c << endl;
    }
};

int main()
{
    Add<double> add("相加的和:"); // 构造对象, 有参构造
    add( 3.1, 2.5 );
    add( 4, 5, 6 );
    return 0;
}
  Add<double> 创建了参数类型为double的模板类Add