C++函数指针

使用对象指针绑定进行调用

C++中因为函数指针需要绑定的对象才能使用,因此使用方法和C语言的函数指针不太一样

当然也可也借用该方法实现对私有函数的外部调用,因为只要使用对象强制取函数地址调用的方式,就忽略了数据保护的作用

#include <thread>
#include <atomic>
#include <cassert>
#include <vector>
#include <iostream>using namespace std;class Widget {public:void Locate() const {cout << " Widget locate " << widget << endl;}private:int widget = 1;
};typedef void (Widget::*LOCATE_FUNC)();class Derive :public Widget {public:void ShowDerive() const {cout << "Derive show " <<  derive << endl;}LOCATE_FUNC GetLocate() {// C++中函数指针需要取地址符return (LOCATE_FUNC)&Derive::DeriveLocate;}
private:void DeriveLocate() const {cout << "derive locate" << derive << endl;}int derive = 3;
};/** 知道函数指针地和对象父类指针如何调用该函数* */
int main(int argc, char*argv[])
{// C++ 函数指针的调用Derive derive;LOCATE_FUNC lpLocate = derive.GetLocate();// 子类对象调用函数指针(derive.*lpLocate)(); // 必须加括号进行调用// 父类指针调用之类对象Widget *lpDerive = &derive;(lpDerive->*lpLocate)();return 0;
}

借用闭包特性来调用实现函数的调用

使用对象指针绑定,虽然也能够起到在其他地方调用成员函数的作用,但是不太方便。我们可以借助lamda的闭包行为来实现函数的调用,如下,使用lamda将函数的this指针通过默认的闭包行为生成一个函数对象,并将函数对象赋值给std::function<int32_t(int32_t)>对象,一旦赋值结束,后期调用函数的时候就不需要再人为的先拿对象指针在拿函数指针进行强制绑定的形式调用了,而且理解起来很方便,对于其他人来说一旦封装好,剩下的就是正常的函数调用了。

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>class CallFunctions {public:int32_t GetData() const {return m_funcGetData();}int32_t SetData(int32_t data) const {return m_funcSetData(data);}public:std::function<int32_t()> m_funcGetData;std::function<int32_t(int32_t)> m_funcSetData;
};class Functions {public:Functions() = default;~Functions() = default;public:int32_t SetData(int32_t data) {if (data < 0) {return -1;}m_data = data;return 0;}int32_t GetData() const {return m_data;}public:void SetFunctions(CallFunctions *lpFunctions) {m_lpCallFunctions = lpFunctions;}void FunctionsInit() {// 使用lamda的闭包行为将this绑定到GetData上,那么其他对象想要调用该对象的成员函数时,就可以直接调用// 不在需要人为的对函数和对象进行绑定在调用指针形式调用函数了auto lamda =  [this]() -> int32_t {return GetData();};m_lpCallFunctions->m_funcGetData = lamda;auto setLamda = [this](int32_t data) -> int32_t {return SetData(data);};m_lpCallFunctions->m_funcSetData = setLamda;}private:CallFunctions *m_lpCallFunctions;int32_t m_data;
};int main(int argc, char *argv[])
{Functions functions{};CallFunctions callFunctions;functions.SetFunctions(&callFunctions);functions.SetData(4);functions.FunctionsInit();std::cout << callFunctions.GetData() << std::endl;functions.SetData(6);std::cout << callFunctions.GetData() << std::endl;callFunctions.SetData(10);std::cout << callFunctions.GetData() << std::endl;return 0;
}

成员函数在外部调用的方式总结-函数指针强制绑定+lamda函数闭包行为实现this指针的绑定相关推荐

  1. python init函数可以外部调用么,如何从python类中调用外部函数

    我试图收集通过套接字解析的数据.这是我的密码:import pickle import SocketServer class SocketReciever(SocketServer.BaseReque ...

  2. c++成员函数指针强制转换为一般函数指针出现问题

  3. JavaScript定义函数的几种方式

    上节我们介绍了<JavaScript工作体系中不可或缺的函数>,函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块.接下来我们说说js当中定义(声明)函数的几种方式,以及每种方式的 ...

  4. JavaScript定义函数的几种方式 1

    上节我们介绍了<JavaScript工作体系中不可或缺的函数>,函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块.接下来我们说说js当中定义(声明)函数的几种方式,以及每种方式的 ...

  5. 使用函数指针实现父类函数调用子类函数的两种方式

    父子类关系 对于继承关系中的父类和子类,我们可以说子类是父类的一种,子类继承了父类的属性和行为.因此,子类可以访问父类的所有非私有成员.相反,父类一般情况下是不能访问子类成员的.然而,我们可以通过一些 ...

  6. js 调用c语言函数看,web前端:JS高级---函数中的this的指向,函数的不同调用方式...

    在程序设计中,常将一些常用的功能模块编写成函数,放在函数库中供公共选用.要善于利用函数,以减少重复编写程序段的工作量. 函数分为全局函数.全局静态函数;在类中还可以定义构造函数.析构函数.拷贝构造函数 ...

  7. JavaScript高级第2天:定义函数的三种方式、函数的原型链结构、完整原型链、作用域以及作用域链、函数的四种调用模式、闭包、计数器、斐波那契数列优化、三种继承方式

    JavaScript高级第二天 01-定义函数的三种方式 1.函数声明 function:可以先调用再声明,因为预解析(把函数声明.变量声明进行提升) function fn() {//函数体conl ...

  8. python open 打开是什么类型的文件-详解Python中open()函数指定文件打开方式的用法...

    文件打开方式 当我们用open()函数去打开文件的时候,有好几种打开的模式. 'r'->只读 'w'->只写,文件已存在则清空,不存在则创建. 'a'->追加,写到文件末尾 'b'- ...

  9. python input与返回值-python中使用input()函数获取用户输入值方式

    我们编写程序最终目的还是来解决实际问题,所以必然会遇到输入输出的交互问题,python中提供了input函数用来获取用户的输入,我们可以用以下程序演示. user_gender = input(&qu ...

最新文章

  1. 想知道spring boot+cloud+docker的微服务体系架构如何使用吗?
  2. c语言中定义结构体指针的作用,c语言定义结构体指针
  3. 从C语言的角度重构数据结构系列(九)-数据结构哈希表分糖果
  4. (11)FPGA跨时钟域处理(第3天)
  5. (69)FPGA模块调用(system Verilog调用Verilog)
  6. 从不同步的代码块中调用了对象同步方法。_Java中Synchronized的用法
  7. 使用Rss框架PHP开发流程
  8. Spring中都用到了那些设计模式
  9. PHP获取git提交信意_代码提交规范检查与修复 php_codesniffer + composer-git-hooks
  10. python global用法_python可视化——pyechart库
  11. Proteus 8.9下载安装指南
  12. 利用VBB仿真——实现24小时电子钟
  13. 英语聊天时“好的”、“我知道了”、“收到”、“嗯嗯”之类的怎么说?
  14. 程序员小抄——GitHub 热点速览 Vol.44
  15. 时间复杂度比较以及额外空间复杂度O(1)
  16. flask导入mysql数据库_flask 数据库报错
  17. 计算机毕业设计SSM电影院购票系统【附源码数据库】
  18. echarts绘制函数曲线
  19. 12个球,其中有1个坏球和其他11个重量不一样,给你一个天平,称3次,找出不一样的那个
  20. 关于matlab中矩阵取值的方法

热门文章

  1. 51`CTO下载中心——我的新爱
  2. struts声明式异常
  3. Android-PopupWindow
  4. Django中的模型继承
  5. 顽石系列:Java技术面试
  6. 洛谷 P1273 【有线电视网】
  7. Kotlin 文档 .Google 正式确定将 Kotlin为android 开发语言
  8. Spring IO Platform简介及示例
  9. To-do-List
  10. 单层感知器应用实例--坐标点的二分类模式分类