c++的可调用对象 有

  • 函数
  • 函数指针
  • lambda表达式
  • bind的对象
  • 重载了函数调用运算符的类

如何调用?

函数调用

void afuncToCall()
{
cout << "call me"<<"\n";
}
//1.call function
afuncToCall();

函数指针调用

void func(int i){
cout << "a function called by function pointer i= "<<i<<"\n";
}
//声明一个函数指针
void(*f)(int i);
//对函数指针赋值
f=func;
//调用指针函数
f(5);

或者使用typedef缩写函数指针

//function pointer
typedef void(*AbleCallFuncP)(int i) ;
//2.function pointer
AbleCallFuncP callFuncPointer= func;
callFuncPointer(5);

lambda表达式调用

auto flambda = [](int i){
cout << "lambda i is " << i << "\n";
};
flambda(7);

bind的对象

#include <functional>
void func(int i){
cout << "a function called by bind object i= "<<i<<"\n";
} auto fbind = bind(func,std::placeholders::_1);
fbind(9);

重载了函数调用运算符的类

struct callableStruct
{
int operator()(int val){
return (val<0)?-val:val;
}
};
// callableStruct callableSut;
int i = callableSut(-2);

函数表

现在,我们拥有了5种函数调用方式,那么,在一个项目里,我们很可能希望使用一个统一的函数表来管理这些函数调用对象,以上面的函数为例,我们其实拥有了5个参数为int类型的调用对象,使用map可以方便地实现函数表;

只是,问题在于,这5种可调用对象的类型是不同的,我们无法将他们使用同一种类型放入map的second字段中,于是万能的C++标准大神们发明了function类模板来解决这个问题。

罗列5种可调对象如下:

//function
void afuncToCall(int i)
{
cout << "call me a plain functon i is "<<i <<"\n";
}
//function pointer
typedef void(*AbleCallFuncP)(int i) ; //called by function pointer
void func1(int i){
cout << "a function called by function pointer i= "<<i<<"\n";
} //called by bind
void func2(int i){
cout << "a function called by bind i= "<<i<<"\n";
} //callable class
struct callableStruct
{
void operator()(int i){
cout << "a function called by callableStruct i= "<<i<<"\n";
}
};
//1.call function
//afuncToCall();
// //2.function pointer
AbleCallFuncP callFuncPointer= func1;
//3.lambda
auto flambda = [](int i){
cout << "lambda i is " << i << "\n";
};
//4 bind
auto fbind = bind(func2,std::placeholders::_1);
//5.operator ()
callableStruct callableSut;

让我们用function统一它们的类型

#include <functional>
#include <map>
#include <string>
// using std::map;
void TestCallableObj()
{
typedef function<void(int)> FuncVI;
typedef map<string,FuncVI> FuncAbleObjMap;
FuncAbleObjMap callableObjMap; callableObjMap.insert(FuncAbleObjMap::value_type(string("plain function call"),afuncToCall));
callableObjMap.insert(FuncAbleObjMap::value_type(string("function pointer call"),callFuncPointer));
callableObjMap.insert(FuncAbleObjMap::value_type(string("lambda call"),flambda));
callableObjMap.insert(FuncAbleObjMap::value_type(string("bind call"),fbind));
callableObjMap.insert(FuncAbleObjMap::value_type(string("operator() call"),callableStruct())); callableObjMap["plain function call"](1);
callableObjMap["function pointer call"](2);
callableObjMap["lambda call"](3);
callableObjMap["bind call"](4);
callableObjMap["operator() call"](5);
}

输出结果

call me a plain functon i is 1
a function called by function pointer i= 2
lambda i is 3
a function called by bind i= 4
a function called by callableStruct i= 5

由此可见,通过function模板,我们将类型本不同的5个可调用对象打包成统一的类型,因为它们的返回值和参数类型是完全一样的。通过函数表的使用,我们可以写出封装更好的调用函数。

如果觉得这样的调用太繁琐,可以使用宏来缩写下

比如:

#define CALL1(x)  callableObjMap[#x](1);
CALL1(plain function call);
CALL1(bind call);

备注,本文没有涉及到函数成员函数 和静态成员函数的调用,权当归类到函数一类了。但是其调用细节和函数还是有差异的。

C++可调用对象与函数表的更多相关文章

  1. C++ 关于类与对象在虚函数表上唯一性问题 浅析

    [摘要] 非常多教材上都有介绍到虚指针.虚函数与虚函数表.有的说类对象共享一个虚函数表,有的说,一个类对象拥有一个虚函数表.还有的说,不管用户声明了多少个类对象,可是,这个VTABLE虚函数表仅仅有一 ...

  2. C++对象内存模型2 (虚函数,虚指针,虚函数表)

    从例子入手,考察如下带有虚函数的类的对象内存模型: class A { public: virtual void vfunc1(); virtual void vfunc2(); void func1 ...

  3. 深入理解类成员函数的调用规则(理解成员函数的内存为什么不会反映在sizeof运算符上、类的静态绑定与动态绑定、虚函数表)

    本文转载自:http://blog.51cto.com/9291927/2148695 总结: 一.成员函数的内存为什么不会反映在sizeof运算符上?             成员函数可以被看作是类 ...

  4. C++对象的内存布局以及虚函数表和虚基表

    C++对象的内存布局以及虚函数表和虚基表 本文为整理文章, 参考: http://blog.csdn.net/haoel/article/details/3081328 http://blog.csd ...

  5. C++虚函数表解析(图文并茂,非常清楚)( 任何妄图使用父类指针想调用子类中的未覆盖父类的成员函数的行为都会被编译器视为非法)good

    C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有“多种形态”,这是一种泛型技术 ...

  6. C++虚函数表和对象存储

    C++虚函数表和对象存储 C++中的虚函数实现了多态的机制,也就是用父类型指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数,这种技术可以让父类的指针有"多种形态",这 ...

  7. C++对象内存模型2 (虚函数,虚指针,虚函数表)(转)

    class A { public: virtual void vfunc1(); virtual void vfunc2(); void func1(); void func2(); virtual ...

  8. C++对象内存分布详解(包括字节对齐和虚函数表)

    转自:https://www.jb51.net/article/101122.htm 1.C++对象的内存分布和虚函数表: C++对象的内存分布和虚函数表注意,对象中保存的是虚函数表指针,而不是虚函数 ...

  9. C++对象的内存分布和虚函数表

    c++中一个类中无非有四种成员:静态数据成员和非静态数据成员,静态函数和非静态函数. 1.非静态数据成员被放在每一个对象体内作为对象专有的数据成员.    2.静态数据成员被提取出来放在程序的静态数据 ...

随机推荐

  1. c primer plus(五版)编程练习-第六章编程练习

    1.编写一个程序,创建一个具有26 个元素的数组,并在其中存储26 个小写字母.并让该程序显示该数组的内容. #include<stdio.h> #define SIZE 26 int m ...

  2. 一个Spark job的生命历程

    一个job的生命历程 dagScheduler.runJob //(1) --> submitJob ( eventProcessLoop.post(JobSubmitted,***) //(2 ...

  3. 小论“Boolean参数作为入参”的函数

    <Clean Code>一书中对于如何写好函数有着很动人的描写,其中对于函数参数的建议有如下两点: 函数参数的数量应该尽可能少 给一个一元函数传入bool类型的参数很"罪恶&qu ...

  4. idea使用插件activate-power-mode给编码加上特效和带来乐趣。

    一.安装. 1. 2. 二.使用. 1. 2.

  5. WPF usercontrol 自定义依赖属性

    1.依赖属性不同意一般属性,一般属性主要定义在对象中,而依赖属性是存在一个特殊的依赖属性表中.2.当我们触发改变值时,需要通过SetValue这种方式进行触发. UserControl1.xaml: ...

  6. bzoj1008 / P3197 [HNOI2008]越狱

    P3197 [HNOI2008]越狱 考虑所有状况:显然是$m^{n}$ 考虑所有不合法状况: 显然相邻两个数不相等 那么后面$n-1$个数就有$(m-1)^{n-1}$种取法 第一个数前面没有相邻的 ...

  7. JS中的slice和splice

    1,slice  : 定义:接收一个或两个参数,它可以创建一个由当前数组中的一项或多项组成的新数组,注意是新数组哦~ 也就是说它不会修改原来数组的值. 用法:slice( para1 ),会截取从pa ...

  8. 解决数据库里表字段带下划线,实体类转小驼峰,Mapper的映射问题

    mybatis中mapUnderscoreToCamelCase的使用 mybatis-config.xml配置: <?xml version="1.0" encoding= ...

  9. Tensorflow源码编译,解决tf提示未使用SSE4.1 SSE4.2 AVX警告【转】

    本文转载自:https://blog.csdn.net/iTaacy/article/details/72799833 版权声明:欢迎转载,转载请注明出处! https://blog.csdn.net ...

  10. python 单向链表

    import sys import random class employee: def __init__(self): self.num= self.salary= self.name='' sel ...