详细请看《C++ Primer plus》(第六版中文版)
http://www.cnblogs.com/lvpengms/archive/2011/02/21/1960078.html
备注:
函数对象:
尽管函数指针被广泛用于实现函数回调,但C++还提供了一个重要的实现回调函数的方法,那就是函数对象。函数对象(也称“函数符”)是重载了“()”操作符的普通类对象。因此从语法上讲,函数对象与普通的函数行为类似。
用函数对象代替函数指针有几个优点:
- 首先,因为对象可以在内部修改而不用改动外部接口,因此设计更灵活,更富有弹性。函数对象也具备有存储先前调用结果的数据成员。在使用普通函数时需要将先前调用的结果存储在全程或者本地静态变量中,但是全程或者本地静态变量有某些我们不愿意看到的缺陷。
- 其次,在函数对象中编译器能实现内联调用,从而更进一步增强了性能。这在函数指针中几乎是不可能实现的。
- C++11还提供了limbda表达式来实现函数的灵活调用。详见《C++ Primer Plus》第18章。
----------------------------------------------------------------------------------------------------------------------------------------------------------
function<bool (int, float)> f;
下面简要介绍一下function的比较重要的几个接口。
--------------------------------------------------------------------------------
function();
template <typename F> function(F g);
这个泛型的构造函数接受一个兼容的函数对象,即这样一个函数或函数对象,它的返回类型与被构造的function的返回类型或者一样,或者可以隐式转换,并且它的参数也要与被构造的function的参数类型或者一样,或者可以隐式转换。
注意,也可以使用另外一个function实例来进行构造。这样做,并且function g为空,则被构造的function也为空。使用空的函数指针和空的成员函数指针也会产生空的function。如果这样做,并且function g为空,则被构造的function也为空。使用空的函数指针和空的成员函数指针也会产生空的function。
--------------------------------------------------------------------------------
template <typename F> function(reference_wrapper<F> g);
function& operator=(const function& g);
template<typename F> function& operator=(F g);
bool empty() const;
void clear();
result_type operator()(Arg1 a1, Arg2 a2, ..., ArgN aN) const;
1 int Add(int x, int y) 2
3 { 4 return x+y; 5 } 6 function<int (int,int)> f = Add; 7 int z = f(2, 3);
2、函数对象
1 class CStudent 2 { 3 public: 4 void operator() (string strName, int nAge) 5 { 6 cout << strName << " : " << nAge << endl; 7 } 8 }; 9
10 CStudent stu; 11 function<void (string, int)> f = stu; 12 f("Mike", 12);
3、类的成员函数
1 struct TAdd 2 { 3 int Add(int x,int y) 4 { 5 return x+y; 6 } 7 }; 8
9 function<int (TAdd *, int, int)> f = TAdd::Add; 10 TAdd tAdd; 11 f(&tAdd, 2, 3); // 如果前面的模板参数为传值或引用,直接传入tAdd即可
接下来我们来看看使用function来保存函数对象状态的情况。考虑下面的代码:
1 class CAdd 2 { 3 public: 4 CAdd():m_nSum(0) { NULL; } 5 int operator()(int i) //重载 () 运算符 6 { 7 m_nSum += i; 8 return m_nSum; 9 } 10
11 int Sum() const
12 { 13 return m_nSum; 14 } 15
16 private: 17 int m_nSum; 18 }; 19
20 int main() 21 { 22 CAdd add; 23 function<int (int)> f1 = add; 24 function<int (int)> f2 = add; 25 cout << f1(10) << "," << f2(10) << "," << add.Sum() << endl; 26 return 0; 27 }
C++ 11中提供了ref和cref函数,来提供对象的引用和常引用的包装。要使function能够正确地保存函数对象的状态,我们可以这样来修改代码:
1 CAdd add; 2 function<int(int)> f1 = ref(add); 3 function<int(int)> f2 = ref(add);