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. POJ1236:Network of Schools(tarjan+缩点)?

    题目: http://poj.org/problem?id=1236 [题意] N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,问题1 ...

  2. 【转】Deep Learning(深度学习)学习笔记整理系列之(五)

    9.2.Sparse Coding稀疏编码 如果我们把输出必须和输入相等的限制放松,同时利用线性代数中基的概念,即O = a1*Φ1 + a2*Φ2+….+ an*Φn, Φi是基,ai是系数,我们可 ...

  3. Mbps MB/S Mb/s

    以前都没有注意这几个的区别,今天百度科普了一下 所谓 10M 带宽,其实是指 10Mbps (兆比特) 1.平时所说的10m带宽,其实是指 10Mbps (兆比特)bit是计算机的最小位单位,1byt ...

  4. ehcache实现页面整体缓存和页面局部缓存

    之前写过spring cache和ehcache的基本介绍和注解实现缓存管理,今天记录下web项目的页面缓存技术. 页面缓存是否有必要?. 这样说吧,几乎所有的网站的首页都是访问率最高的,而首页上的数 ...

  5. c/c++获取系统时间函数

    参考:http://blog.sina.com.cn/s/blog_6f2caee40100uu41.html   Coordinated Universal Time(UTC): 协调世界时,又称为 ...

  6. JAVA面试题整理(6)-JVM

    JVM 1.详细jvm内存模型 2.讲讲什么情况下回出现内存溢出,内存泄漏? 3.说说Java线程栈 4.JVM 年轻代到年老代的晋升过程的判断条件是什么呢? 5.JVM 出现 fullGC 很频繁, ...

  7. Mybatis的executor

    前提:一级缓存与二级缓存,可见:https://www.cnblogs.com/yanze/p/10175017.html 简介: Executor与SqlSession绑定在一起,每一个SqlSes ...

  8. 20145309 李昊 《网络攻防》 Exp2 后门原理与实践

    实践内容: (1)理解免杀技术原理(1分) (2)正确使用msf编码器,veil-evasion,自己利用shellcode编程等免杀工具或技巧:(2分) (3)通过组合应用各种技术实现恶意代码免杀( ...

  9. QT+VS中ui不能声明为指针?

    问题描述:QtCreator里的UI全是默认为指针类型,调用的时候[ui->]但是使用VS+Qt来,发来默认的是变量类型,使用的时候[ui.] 统一:为了统一我把后者声明改为前者 问题:在mai ...

  10. xss总结(一直更新)

    反射型: 在表单输入jack网页源代码:<pre>Hello jack</pre> 测试: 低级别:<script>alert('xss')</script& ...