函数对象有时也叫仿函数,其本质是一个类对象,由于重载函数调用符号,其可以像普通函一样使用。
- 函数调用符号重载语法 {#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;
}