函数对象有时也叫仿函数,其本质是一个类对象,由于重载函数调用符号,其可以像普通函一样使用。
- 函数调用符号重载语法 {#title-0} ========================
class Demo { public: // 返回值:由自己来定义 void operator()() { cout << "hello world" << endl; }
int operator()(int a, int b) { return a + b; }
};
// 函数调用符号:(), C++支持对该运算符重载。类重载函数调用符号之后,就可以像普通函数一样调用了。 void test01() { // 1.1 语法 Demo demo1; demo1(); // demo1.operator()() cout << demo1(10, 20) << endl; // demo1.operator()(10, 20) // 函数重载了函数调用符号之后,叫做函数对象,仿函数
// 1.2 函数对象的赋值 Demo demo2 = demo1; demo2(); demo2(10, 20);
function<void()> demo3 = demo1; demo3(); function<int(int, int)> demo4 = demo1; cout << demo4(10, 20) << endl;
}
- 函数对象相对于普通函数的优点 {#title-1} ============================
C++中使用函数对象作为函数调用,而不是再使用函数指针。
- 函数对象本质是一个类,当调用函数对象时,实际执行的是成员函数。类内定义的函数自动成为内联函数。
- 函数对象是有类型的,可以使用类型再定义函数对象出来。但是,普通函数是没有类型,无法再创建出来函数。
- 函数对象本质上一个类,所以,其可以拥有成员,具有更加丰富表现能力。而普通函数不行: 统计函数调用次数
int cnt = 0; void func() { ++cnt; }
class Functor { public: Functor() { m_cnt = 0; }
void operator()() { ++m_cnt; show(); }
void show() {
}
public: int m_cnt; };
- lambda 和 函数对象 {#title-2} ===========================
lambda 是匿名的函数对象,本质上也是一个类对象,并不是简单的匿名普通函数。
void test02() { auto f = []() {}; cout << typeid(f).name() << endl;
auto f1 = [](int a, int b) { cout << a << " " << b << endl; }; /* class 随机名字 { public: void operator()(int a, int b) const { cout << a << " " << b << endl; } }
随机名字 对象;
*/
int num1 = 100; int num2 = 200; auto f2 = = mutable { num1 = 100; }; // lambda 表达式默认进行值捕获的时候,是无法修改,原因就是 operator() 函数是用 const 修饰 /* class 随机名字 { public: 随机名字(int a, int b): num1(a), num2(b){} void operator()() const { num1 = 100; } public: mutable int num1; mutable int num2; } */
auto f3 = & { num1 = 100; }; /* class 随机名字 { public: 随机名字(): num1(num1), num2(num2){} void operator()() const { num1 = 100; } public: int &num1; int &num2; } */
auto ff1 = = {}; function<void()> ff2 = = {};
// 下面这种方式无法进行外部变量捕获 // 如果 lambda 捕获外部变量,则其必须以对象的形式存在。 // 如果 Lambda 不捕获外部变量,该对象仅仅是独立可以运行的成员函数。 void(ff3)() = {}; / class 随机名字 { public: void operator()() const {
} }
*/
}
- 函数对象使用举例 {#title-3} ======================
struct MyCompare { bool operator()(int num1, int num2) { return num1 > num2; } };
void test03() { // C 语言中使用 qsort 函数排序 // C++ 中使用 sort 函数排序
int arr[] = { 9, 2, 1, 8, 4, 6, 5 };
for (auto val : arr) { cout << val << " "; } cout << endl;
// sort 函数前两个参数是一个区间,第一个元素的位置,最后一个元素的下一个位置 sort(arr, &arr[6] + 1, MyCompare());
for (auto val : arr) { cout << val << " "; } cout << endl;
}