zoukankan      html  css  js  c++  java
  • 函数对象

    首先我们看一下函数指针。

    函数指针是指向函数的指针变量,在编译程序时,每一个函数都有一个入口地址,而指向这个函数的函数指针便指向这个地址。函数指针的作用主要有两个:用作调用函数和用作函数的参数。

    函数指针用作调用函数的实例如下:

    #include <iostream>
    using namespace std;
    typedef void (*PFT) ( char ,int );
    void bar(char ch, int i)
    {
        cout<<ch<<' '<<i<<endl;
    }
    int main()
    {
        PFT pft;
        pft=bar;
        pft('e',91);
        return 0;
    }

    我们可以在一个函数的形参列表中传入一个函数指针,然后便可以在这个函数中使用该函数指针所指向的函数,这样可以使程序变得更加清晰和简洁。函数指针用作函数参数的实例如下:

    #include <iostream>
    using namespace std;
    typedef void (*PFT) ( char ,int );
    void bar(char ch, int i)
    {
        cout<<ch<<' '<<i<<endl;
    }
    void func(char ch,int i,PFT pf)
    {
        pf(ch,i);
    }
    int main()
    {
        PFT pft;
        pft=bar;
        func('e',91,pft);
        return 0;
    }

    上述例子中我们首先利用一个函数指针pft来指向函数bar,然后在函数func中使用函数指针pft来调用函数bar。将这个特点稍加利用,我们就可以构造出强大的程序,只需要用同样的func函数便可以实现对不同bar函数的调用。

    前面讲的是函数指针的应用,从一般的函数回调意义上来说,函数对象和函数指针是相同的,但是函数对象却具有许多函数指针所不具有的特点,从而使得程序设计更加灵活,而且能够实现函数的内联(inline)调用,使整个程序实现性能加速。

    重载函数调用操作符的类,其对象常称为函数对象,即它们是行为类似函数的对象。一个类对象,表现出一个函数的特征,就是通过“对象名+(参数列表)”的方式来实现的,如果没有上下文,完全可以把它看作一个函数对待。这是通过重载类的operator()来实现的,如下:

    #include <iostream>
    using namespace std;
    class A
    {
    public:
        int operator()(int x){return x;}
    };
    int main()
    {
        A a;
        a(5);
        return 0;
    }

    这样a就成为一个函数对象,当我们执行a(5)时,实际上就是利用了重载运算符函数operator(),函数对象既然是一个类对象,那么我们当然可以在函数形参列表中调用它,它完全可以取代指针,如下:

    #include <iostream>
    using namespace std;
    class Func
    {
    public:
        void operator()(int a ,int b)
        {
            cout<<a<<'+'<<b<<'='<<a+b<<endl;
        }
    };
    void addFunc(int a,int b,Func &func)
    {
        func(a,b);
    }
    int main()
    {
        Func func;
        addFunc(1,3,func);
        return 0;
    }

    上述例子中首先定义了一个函数对象类,并重载了operator()函数,然后在函数addFunc中的形参列表中使用这个类对象。

    如果运用泛型思维来考虑,可以定义一个函数模板类,来实现一般类型的数据相加减等操作,如下:

    #include <iostream>
    using namespace std;
    class Func
    {
    public:
        template<class T>
        void operator()(T a ,T b)
        {
            cout<<a<<'+'<<b<<'='<<a+b<<endl;
        }
    };
    template<class T>
    void addFunc(T a,T b,Func &func)
    {
        func(a,b);
    }
    int main()
    {
        Func func;
        addFunc(1,3,func);
        addFunc(1.4,2.3,func);
        return 0;
    }
  • 相关阅读:
    Nucleus 的网络部分
    VS2005中TextBox的ReadOnly属性(转贴)
    VS2005中TextBox的ReadOnly属性导致的问题
    外部中断
    Linux操作系统文件链接问题
    IIS 服务不能自动启动
    转贴:[C++]static用法
    串口测试的一些体会
    字符串的两种声明方式
    Tornado 2.2 中vxsim出问题的解决方法
  • 原文地址:https://www.cnblogs.com/kevinq/p/4605981.html
Copyright © 2011-2022 走看看