什么是C++中的可调用对象?
所谓对象
,就是在内存中存在的具体实例。
那可调用对象
,就是可以像函数一样调用的对象。
C++中有哪些可调用对象?
- 函数与函数指针 (继承自C)
- 仿函数
Lambda
表达式
函数与函数指针
最基本的可以调用的对象就是函数,而指向某个函数的函数指针,也是可调用的
仿函数
什么是仿函数?
首先仿函数是一个自定义的class实例
, 然后这个实例可以指定参数调用自己,实现像函数一样的行为
仿函数原理
调用自己,指的是可以以圆括号加参数的形式, 像函数一行执行, 执行的函数就是这个示例对应的圆括号函数重载. 如:
// Less类型实现了圆括号的操作符重载,参数为int a, int b, 实现的功能是判断a是否小于b
class Less {
public:
bool operator()(int a, int b)
{
return a < b;
}
};
Less less; // 定义一个Less对象实例less, 则less实例就是仿函数
std::cout << less(0, 1) << std::endl; // 0 < 1, 输出1, 对应true
std::cout << less(100, 50) << std::endl; // 100不小于50, 对应false
std::cout << less(10, 10) << std::endl; // 10不小于10, 对应false
为什么要用仿函数?
疑问1: 已经有了函数指针了,为什么还需要仿函数?
- 首先函数指针只能指向一般的函数,并且除了函数指定的参数外,没有办法传递多余的参数,使用场景有限
- 函数指针属于运行时动态函数,调用前需要确保指针合法,仿函数一般不需要额外判断,且更安全
- 函数指针调用时,需要对指针解引用,与仿函数相比,效率更低,仿函数属于编译期函数跳转
- 仿函数除了调用参数外,可以通过类构造函数传入额外的参数,这一点函数指针做不到,比如:
// 有一个外部函数, 用来过滤数据
template<Func>
std::vector<int> filter(Func&& func