()运算符重载为成员函数,这个类就称为函数对象类,这个类的对象就是函数对象。函数对象是一个对象,但是使用的形式看起来像函数调用,实际上也执行了函数调用,因而得名。
#include <iostream>
using namespace std;
class CAverage
{
public:
double operator()(int a1, int a2, int a3)
{ //重载()运算符
return (double)(a1 + a2 + a3) / 3;
}
};
int main()
{
CAverage average; //能够求三个整数平均数的函数对象
cout << average(3, 2, 3); //等价于 cout << average.operator(3, 2, 3);
return 0;
}
程序的输出结果是:()是目数不限的运算符,因此重载为成员函数时,有多少个参数都可以。
template <class InIt, class T, class Pred>
T accumulate(InIt first, InIt last, T val, Pred op);
template <class InIt, class T, class Pred>
T accumulate(InIt first, Init last, T init, Pred op)
{
for (; first != last; ++first)
init = op(init, *first);
return init;
};
此模板被实例化后,op(init, *first)必须要有定义,则 op 只能是函数指针或者函数对象。因此调用该 accmulate 模板时,形参 op 对应的实参只能是函数名、函数指针或者函数对象。
#include <iostream>
#include <vector>
#include <numeric> //accumulate 在此头文件定义
using namespace std;
template <class T>
void PrintInterval(T first, T last)
{ //输出区间[first,last)中的元素
for (; first != last; ++first)
cout << *first << " ";
cout << endl;
}
int SumSquares(int total, int value)
{
return total + value * value;
}
template<class T>
class SumPowers
{
private:
int power;
public:
SumPowers(int p) :power(p) { }
const T operator() (const T & total, const T & value)
{ //计算 value的power次方,加到total上
T v = value;
for (int i = 0; i < power - 1; ++i)
v = v * value;
return total + v;
}
};
int main()
{
const int SIZE = 10;
int a1[] = { 1,2,3,4,5,6,7,8,9,10 };
vector<int> v(a1, a1 + SIZE);
cout << "1) "; PrintInterval(v.begin(), v.end());
int result = accumulate(v.begin(), v.end(), 0, SumSquares);
cout << "2) 平方和:" << result << endl;
result = accumulate(v.begin(), v.end(), 0, SumPowers<int>(3));
cout << "3) 立方和:" << result << endl;
result = accumulate(v.begin(), v.end(), 0, SumPowers<int>(4));
cout << "4) 4次方和:" << result;
return 0;
}
程序的输出结果如下:
int accumulate(vector <int>::iterator first, vector <int>::iterator last, int init, int(*op)(int, int))
{
for (; first != last; ++first)
init = op(init, *first);
return init;
}
形参 op 是一个函数指针,而op(init, *first)就调用了指针 op 指向的函数,在第 37 行的情况下就是函数 SumSquares。
int accumulate(vector<int>::iterator first, vector<int>::iterator last, int init, SumPowers<int> op)
{
for (; first != last; ++first)
init = op(init, *first);
return init;
}
形参 op 是一个函数对象,而op(init, *first)等价于:
op.operator()(init, *first);
即调用了 SumPowers<int> 类的 operator() 成员函数。
template <class_Randlt>
void sort(_Randlt first, _RandIt last);
<进行的。如果表达式a<b的值为 true,则 a 排在 b 前面;如果a<b的值为 false,则 b 未必排在 a 前面,还要看b<a是否成立,成立的话 b 才排在 a 前面。要使用这个版本的 sort 算法,待排序的对象必须能用<运算符进行比较。
template <class_Randlt, class Pred>
void sort(_Randlt first, _RandIt last, Pred op);
op(a, b)进行的。如果该表达式的值为 true,则 a 比 b 小;如果该表达式的值为 false,也不能认为 b 比 a 小,还要看op(b, a)的值。总之,op 定义了元素比较大小的规则。下面是一个使用 sort 算法的例子。
#include <iostream>
#include <algorithm> //sort算法在此头文件中定义
using namespace std;
template <class T>
void Printlnterva1(T first, T last)
{ //用以输出 [first, last) 区间中的元素
for (; first != last; ++first)
cout << *first << " ";
cout << endl;
}
class A
{
public:
int v;
A(int n) : v(n) {}
};
bool operator < (const A & a1, const A & a2)
{ //重载为 A 的 const 成员函数也可以,重载为非 const 成员函数在某些编译器上会出错
return a1.v < a2.v;
}
bool GreaterA(const A & a1, const A & a2)
{ //v值大的元素作为较小的数
return a1.v > a2.v;
}
struct LessA
{
bool operator() (const A & a1, const A & a2)
{ //v的个位数小的元素就作为较小的数
return (a1.v % 10) < (a2.v % 10);
}
};
ostream & operator << (ostream & o, const A & a)
{
o << a.v;
return o;
}
int main()
{
int a1[4] = { 5, 2, 4, 1 };
A a2[5] = { 13, 12, 9, 8, 16 };
sort(a1, a1 + 4);
cout << "1)"; Printlnterva1(a1, a1 + 4); //输出 1)1 2 4 5
sort(a2, a2 + 5); //按v的值从小到大排序
cout << "2)"; Printlnterva1(a2, a2 + 5); //输出 2)8 9 12 13 16
sort(a2, a2 + 5, GreaterA); //按v的值从大到小排序
cout << "3)"; Printlnterva1(a2, a2 + 5); //输出 3)16 13 12 9 8
sort(a2, a2 + 5, LessA()); //按v的个位数从小到大排序
cout << "4)"; Printlnterva1(a2, a2 + 5); //输出 4)12 13 16 8 9
return 0;
}
编译至第 45 行时,编译器将 sort 实例化得到的函数原型如下:
void sort(A* first, A* last, bool (*op)(const A &, const A &) );
该函数在执行过程中,当要比较两个元素 a、b 的大小时,就是看 op(a, b) 和 op(b, a) 的返回值。本程序中 op 指向 GreaterA,因此就用 GreaterA 定义的规则来比较大小。void sort( A* first, A* last, LessA op);
该函数在执行过程中,当要比较两个元素 a、b 的大小时,就是看 op(a, b) 和 op(b, a) 的返回值。本程序中,op(a, b) 等价于 op.opeartor(a, b),因此就用 LessA 定义的规则来比较大小。
template <class T>
struct greater
{
bool operator()(const T& x, const T& y) const{
return x > y;
}
};
假设有以下数组:
int a[4] = {3, 5, 34, 8};
要将该数组从大到小排序,则只需写:sort( a, a+4, greater<int>() );
要使用 greater 模板,须确保>运算符本来就有定义,或经过了适当的重载。<运算符;另一个是函数模板,原型如下:
template <class Pred>
void sort(Pred op);
list<int> lst;
如果希望将 lst 中的元素按其整数数值从大到小排序,只需写:lst.sort( greater<int>() );
在使用关联容器和许多算法时,都可以用函数对象来定义比较大小的规则,以及其他一些规则和操作。| 函数对象类模板 | 成员函数 T operator ( const T & x, const T & y) 的功能 |
|---|---|
| plus <T> | return x + y; |
| minus < > | return x - y; |
| multiplies <T> | return x * y; |
| divides <T> | return x / y; |
| modulus <T> | return x % y; |
| 成员函数 bool operator( const T & x, const T & y) 的功能 | |
| equal_to <T> | return x == y; |
| not_equal_to <T> | return x! = y; |
| greater <T> | return x > y; |
| less <T> | return x < y; |
| greater_equal <T> | return x > = y; |
| less_equal <T> | return x <= y; |
| logical_and <T> | return x && y; |
| logical_or <T> | return x || y; |
| 成员函数 T operator( const T & x) 的功能 | |
| negate <T> | return - x; |
| 成员函数 bool operator( const T & x) 的功能 | |
| logical_not <T> | return ! x; |
multiplies<double> () (x, y)
template <class_Tp>
struct less
{
bool operator() (const_Tp & __x, const_Tp & __y) const
{ return __x < __y; }
};
要判断两个 int 变量 x、y 中 x 是否比 y 小,可以写:
if( less<int>()(x, y) ) { ... }
<运算符进行的。通过 10.3.4 节可知,sort 和 list::sort 都可以通过一个函数对象或函数自定义比较元素大小的规则。例如以下的 sort 版本:
template <class_RandIt, class Pred>
void sort(_RandIt first, _RandIt last, Pred op);
<运算符,以规定元素之间的大小关系。STL 中还有许多算法都可以自定义比较器。在自定义比较器 op 的情况下,以下三种说法是等价的:
x和y相等与op(x, y)和op(y, x)都为假是等价的。
版权说明:Copyright © 广州松河信息科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州松河信息科技有限公司 版权所有