函数适配器2——成员函数适配器

来源:互联网 发布:java通过ftp上传文件 编辑:程序博客网 时间:2024/06/06 01:47

1.1 定义:

      本质是一个类,是一个像使用函数一样直接名称+括号就可以调用的类,事实上就是一个重载了operator()函数的类。

1.2 目的:

      具有内部状态的功能,这是函数所不能比拟的。

1.3 例子:

#include "stdafx.h"
#include 
<vector>
#include 
<string>
#include 
<algorithm>
#include 
<iostream>

using std::string;

class Person
{
public:
    Person(
string init): name(init)
    {
    }
    
string name;
};

class PersonCriterion    //这个就是仿函数,用于比较两个名字的长短
{
public:
    
bool operator() (const Person& t1, const Person& t2)
    {
        std::cout 
<< "" << ++count << "次调用" << std::endl;    //通过他可以很清晰地知道函数调用多少次
        return t1.name.length() < t2.name.length();
    }
private:
    
static int count;
};
int PersonCriterion::count = 0;

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector
<Person> iv;
    iv.push_back(Person(
"one"));
    iv.push_back(Person(
"two"));
    iv.push_back(Person(
"three"));
    iv.push_back(Person(
"four"));

    
//将类像函数一样将指针传递进去,sort将调用 PersonCriterion::operator() 对vector进行排序。
    std::sort(iv.begin(), iv.end(), PersonCriterion() );

    
for (std::vector<Person>::iterator it = iv.begin();
        it 
!= iv.end();
        
++it)
    {
        std::cout 
<< (*it).name << " ";
    }
    
return 0;
}

最后的结果可能根据STL的实作可能会有所区别。

2 函数配接器:

2.1 定义:

      函数配接器是一种特殊的仿函数。能够将仿函数和另外一个仿函数结合起来的函数或者说是一个将仿函数作为参数的仿函数。预先定义好的函数配接器有

            bind1st(op, value),

            bind2nd(op, value),

            not1(op),

            not2(op)

2.2 分类:

      函数适配器有两种:

            针对一般函数(非成员函数)而设计的函数适配器

            针对成员函数而设计的函数适配器

2.3 针对一般函数(非成员函数)而设计的函数适配器:

      这种是我们最经常使用的用法。通过函数适配器对一个参数进行绑定。

#include "stdafx.h"
#include 
<vector>
#include 
<string>
#include 
<algorithm>
#include 
<iostream>

using std::string;

class Person
{
public:
    Person(
string init): name(init)
    {
    }
    
string name;
};

bool  shorter (const Person& t1, const Person& t2)
{
    
return t1.name.length() < t2.name.length();
}


int _tmain(int argc, _TCHAR* argv[])
{
    std::vector
<Person> iv;
    iv.push_back(Person(
"one"));
    iv.push_back(Person(
"two"));
    iv.push_back(Person(
"three"));
    iv.push_back(Person(
"four"));

    
//将函数指针传递进去
    std::sort(iv.begin(), iv.end(), shorter);

    
for (std::vector<Person>::iterator it = iv.begin();
        it 
!= iv.end();
        
++it)
    {
        std::cout 
<< (*it).name << " ";
    }
    
return 0;
}


2.4 针对成员函数而设计的函数配接器

      这里所说的成员函数不包括operator(). 这种用法不多见。是通过mem_fun_ref进行转换,将原本针对某个元素的函数调用转为调用被传递变量(*itr  itr为iv的迭代器)的成员函数。

#include "stdafx.h"
#include 
<vector>
#include 
<string>
#include 
<functional>
#include 
<algorithm>
#include 
<iostream>

using std::string;

class Person
{
public:
    Person(
string init): name(init)
    {
    }

    
//以成员函数调用,故可忽略const Person& t1
    bool shorter(const Person& t2) const
    {
        std::cout 
<< "" << ++count << "次调用" << std::endl;
        
return name.length() < t2.name.length();
    }
    
string name;
    
static int count;
};
int Person::count = 0;


int _tmain(int argc, _TCHAR* argv[])
{
    std::vector
<Person> iv;
    iv.push_back(Person(
"one"));
    iv.push_back(Person(
"two"));
    iv.push_back(Person(
"three"));
    iv.push_back(Person(
"four"));

    std::sort(iv.begin(), iv.end(), std::mem_fun_ref(
&Person::shorter) );

    
for (std::vector<Person>::iterator it = iv.begin();
        it 
!= iv.end();
        
++it)
    {
        std::cout 
<< (*it).name << " ";
    }
    
return 0;
}

  mem_fun_ref和mem_fun的区别:

                                          若集合是基于对象的,形如 vector<student>,则用mem_fun_ref

                                          若集合是基于对象指针的,形如 vector<student*>,则用mem_fun


2.5 可以使用函数配接器的自定义仿函数

      函数配接器只能用在系统仿函数(例如less)中,如果我们想要我们的仿函数能够使用函数配接器,必须然类从unary_function或 binary_function派生而来。因为函数适配器里面用到了参数的特定成员(例如T1::argument_type, T1::result_type),所以我们只要在类继承列表里添加

public std::unary_function<T1,T1>

或public std::binary_function<T1,T2,T1>即可


0 0
原创粉丝点击