关闭

函数对象

标签: classstring算法vectoriostreamstruct
2138人阅读 评论(0) 收藏 举报
分类:
利用C++标准模板库的算法可以为我们减轻许多负担,但这些算法大都需要函数或函数对象作为参数,比如用于排序的sort算法,它的接口定义如下:
template <class RandomAccessIterator>
void sort (RandomAccessIterator first,
           RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
void sort (RandomAccessIterator first,
           RandomAccessIterator last, Compare comp);
第1种语法只适合对属于基本数据类型的对象排序,它使用<作为排序比较规则,第2种语法则是根据指定排序规则comp来进行排序,其中comp参数就是一个函数对象。如果要排序的对象不是如int,float等简单类型或不想使用<作为排序规则的话就得使用第2种语法,指定一个函数对象来作为排序规则(函数对象)进行排序,那函数对象究竟是什么了,其实简单地说它就是一些使用起来像调用函数一样的对象,如:一般的函数,函数指针,或重载了()运算符的类的实例等,使用这些对象的方式好像调用函数一样所以称这些对象为函数对象,如下就是函数对象定义:
//一般函数
 void print(int x)
{
       if(x>=0&&x<=100) cout<<x<<” ”;
}
       //函数对象指针
typedef void(*ptPrint)(int x);
ptPrint prt=print;
//一个重载了()运算符得类
class isOk
{
 public:
 bool operator () (int val)
 {
       if(val<0||val>100)
{
       return false;
}
 return true;
}
};
有了上面得定义后,我们就可以以函数调用的形式使用上面的函数对象了,如: for_each(vectorA.begin(),vectorA.end(),print)打印大于等于0小于等于100的数, transform(vectorA.begin(),vectorA.end(),vectorB.begin(),isOk())判断向量vectorA中值x的范围是否在0之100之间,如果在则向量vectorB对应的值为真,否则为假,其中vectorB中的数据类型为bool。在实际中往往会根据调用函数对象时参数的多少将函数对象分为三种形式,,无参函数对象,一元函数对象和二元函数对象,刚才的isOK()就是一个无参函数对象。无参函数对象与一元,二元函数对象有很大的区别,一元,二元函数对象的定义需要继承以下函数原型:
       //一元函数对象函数原型
template <class Arg, class Result>
struct unary_function {
 typedef Arg argument_type;
 typedef Result result_type;
};
       //二元函数对象函数原型
template <class Arg1, class Arg2, class Result>
struct binary_function {
 typedef Arg1 first_argument_type;
 typedef Arg2 second_argument_type;
 typedef Result result_type;
};
Result为函数返回值,如果我们要定义一元或二元函数对象的话需要继承这两个函数对象的原型,如:
class gradeCompare : binary_function<Grade,Grade, bool> {
public:
 bool operator () (Grade X,Grade Y) const
     {
        return X.Score>Y.Score;
     }
};
上面就是一个二元函数对象的类,该类的实例就是二元函数对象,考虑如下情况:      
有许多学生的成绩情况以对象的形式存在于一个向量vector中,现在我们需要对这些学生成绩进行排序,使用标准模板库的sort算法,学生成绩包含许多字段,如学号,姓名,成绩三个字段,成绩情况的对象定义如下:
class Grade
{
public:
    Grade(int id,string name,int score)
    {
        ID=id;
        Name=name;
        Score=score;
    }
    int ID;
    string Name;
    int Score;
};
 
根据sort算法的原型,我们就必须定义一个用于比较学生成绩的函数对象如下:
class gradeCompare : binary_function<Grade,Grade, bool> {
public:
 bool operator () (Grade X,Grade Y) const
     {
        return X.Score>Y.Score;
     }
};
 
当定义了用于排序的函数对象后就可以直接调用sort算法进行排序了。
 
sort(finalGrade.begin(),finalGrade.end(),gradeCompare());//finalGrade是用来存储学生成绩的向量
 
整个源代码如下:
//---------------------------------------------------------------------------
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std; //使用标准模板库的命名空间
 
//---------------------------------------------------------------------------
 
#pragma argsused
class Grade
{
public:
    Grade(int id,string name,int score)
    {
        ID=id;
        Name=name;
        Score=score;
    }
    int ID;
    string Name;
    int Score;
};
       //打印学生成绩
void printScore(Grade grade)
{
    cout<<grade.ID<<" "<<grade.Name<<" "<<grade.Score<<endl;
}
       //定义函数对象用来排序
class gradeCompare : binary_function<Grade,Grade, bool> {
public:
 bool operator () (Grade X,Grade Y) const
     {
        return X.Score>Y.Score;
     }
};
 
int main(int argc, char* argv[])
{
    vector<Grade>finalGrade;
    finalGrade.push_back(Grade(1,"A",56));
    finalGrade.push_back(Grade(2,"B",57));
    finalGrade.push_back(Grade(3,"C",58));
    sort(finalGrade.begin(),finalGrade.end(),gradeCompare());
    for_each(finalGrade.begin(),finalGrade.end(),printScore);
    return 0;
}
 
结果如下:
3 C 58
2 B 57
1 A 56
 
 
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:74078次
    • 积分:1042
    • 等级:
    • 排名:千里之外
    • 原创:26篇
    • 转载:23篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论