您的位置:首页 > 编程语言 > C语言/C++

【C++基础之十九】函数对象

2013-12-20 09:05 253 查看
原创作品,转载请标明http://blog.csdn.net/jackystudio/article/details/17435117

函数指针倒是蛮常见的,这函数对象又是什么呢?什么时候会用到函数对象?

1.什么是函数对象

函数对象就是定义了函数调用操作符,也就是operator()的对象。因此我们可以在定义函数调用操作符的时候,实现所需的函数功能。

2.示例

如上,其实最主要的还是operate()的定义,这和普通运算符的重载是一样的。[cpp] view plaincopytemplate <typename T>  
class Max  
{  
public:  
    T operator()(T a, T b){ return a>b?a:b;}  
};  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    Max<int> intMax;  
    cout<<intMax(50,60)<<endl;  
    cout<<intMax.operator ()(50,60)<<endl;  
}  

(1)程序定义了一个Max类(这里用了模版),重载了函数调用符,实现了函数功能:返回一个最大值。(2)主函数中定义了一个Max类的对象,intMax,也就是函数对象。(3)对函数调用符的使用,可以直接用括号,也可以用operate+括号的形式(从本质上来说,这是一个特殊的成员函数)。这和普通运算符的重载也是一样的。

3.什么时候用函数对象?

看了上面是例子,可能感觉怪怪的,明明一个函数就能搞定的事,为什么要搞个函数对象出来,函数对象到底用在哪?正是因为函数对象是一个对象,所以它可以封装一些属性,比如函数调用的一些状态数据等等,而函数本身没有记忆功能,从这方面而言,函数比起函数对象弱爆了。函数对象就可以帮我们记住函数做了什么。再看一个例子。[cpp] view plaincopy//定义学生类,重载了输出操作符  
class Student  
{  
public:  
    Student(string strName):name(strName){}  
    friend ostream& operator<< (ostream& out, const Student& stu);  
private:  
    string name;  
};  
  
ostream& operator<< (ostream& out, const Student& stu){out<<stu.name<<endl;return out;}  
  
//定义点名类,定义调用操作符实现点名功能,同时保存学生人数  
template <typename T>  
class NumberOff  
{  
public:  
    NumberOff():m_count(0){}  
    void operator()(const T& t)  
    {  
        cout<<t;  
        m_count++;  
    }  
    int GetCount() const {return m_count;}  
private:  
    int m_count;  
};  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    NumberOff<Student> numberoff;//创建函数对象  
    Student stu1("Jacky1");//创建Student对象  
    Student stu2("Jacky2");  
    Student stu3("Jacky3");  
    numberoff(stu1);//点名  
    numberoff(stu2);  
    numberoff(stu3);  
    cout<<"Total "<<numberoff.GetCount();//输出已点名人数  
}  
输出:
Jacky1
Jacky2
Jacky3
Total 3

这样一来函数对象numberoff中的m_count就帮我们记住了函数调用的次数,也就是已点名学生的人数,就单这个例子而言完全可以写出一个更好的实现,这里举此例主要用于体现函数对象的优势。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息