C++回调函数、静态函数、成员函数踩过的坑。

明确一点即回调函数需要是静态函数。原因:

  • 普通的C++成员函数都隐含了一个this指针作为参数,这样使得回调函数的参数和成员函数参数个数不匹配。

若不想使用C式函数作为回调函数呢?(破坏封装性)

解决方法

  • 使用static修饰成员函数。static不含this指针。
  • 不用static修饰的成员函数,需要借助中间变量来访问。这个演示的很好。
  • 也可以在回调函数中增加一个变量,类型为该类的类型,作为this指针的传递。

下面讲解一下第二点,我认为比较好用。

class A
{
public:
static void staticmember(){cout<<"static"<<endl;} //static member
void nonstatic(){cout<<"nonstatic"<<endl;} //nonstatic member
virtual void virtualmember(){cout<<"virtual"<<endl;};//virtual member
};
int main()
{
A a;
//static成员函数,取得的是该函数在内存中的实际地址,而且因为static成员是全局的,所以不能用A::限定符
void (*ptrstatic)() = &A::staticmember;
//nonstatic成员函数 取得的是该函数在内存中的实际地址
void (A::*ptrnonstatic)() = &A::nonstatic;
//虚函数取得的是虚函数表中的偏移值,这样可以保证能过指针调用时同样的多态效果
void (A::*ptrvirtual)() = &A::virtualmember;
//函数指针的使用方式
ptrstatic();
(a.*ptrnonstatic)();
(a.*ptrvirtual)();
}

直接用类名引出非静态成员函数,赋值给函数指针:

//nonstatic成员函数 取得的是该函数在内存中的实际地址
void (A::*ptrnonstatic)() = &A::nonstatic;

随后需要运行回调函数的时候,使用一个辅助变量来运行,格式为:(变量名. * 函数指针)(参数)

(a.*ptrnonstatic)();

应用:类中成员函数的函数指针写法

如果在我们的编程过程中:

  1. 需要使用到回调函数。
  2. 回调函数是一个类的成员函数。
  3. 此成员函数不是静态函数,也不适合做静态函数。

我们可以使用:

bool (DoTask::*function)(void *arg);

其中DoTask是一个类名,上面写的就是一个返回值为bool类型,参数为void *类型的函数指针,指向DoTask这个类中的成员函数。

然后调用的时候我们可以:

Dotask d;
//注意ReadData函数不用加括号,要加作用域和地址符
bool (DoTask::*function)(void *arg) = &DoTask::ReadData;
(d.*function)(NULL);

注意点就是赋值给函数指针的时候需要取地址符、加作用域、函数不加括号,直接函数名即可。

调用的时候,用一个实例去调用函数指针即可。

其它

假如我们将函数指针放在一个结构体中:

struct task
{
bool (DoTask::*function)(void *arg);
void *arg;
};

那么我们调用它的时候也是一样的。

struct task t;
t.function = &DoTask::ReadData;
...
DoTask d;
(d.*(t.function))(NULL); //完成调用。

现在看调用这一步。参照上面的:

(d.*function)(NULL)

只不过function现在存在结构体中,替换成从结构体中取出来即可:

function 替换成 t.function

代入即可。

C++回调函数、静态函数、成员函数踩过的坑。的更多相关文章

  1. golang写业务代码,用全局函数还是成员函数

    在golang中,函数划分为全局函数和成员函数,在使用的时候,有种情况,会产生一些疑惑的,就是在写业务代码的时候,使用全局函数好像会比较方便,一般业务代码,都不会复用,都是针对特定的业务进行编程,要复 ...

  2. C++基础 (4) 第四天 this指针 全局函数和成员函数 友元 操作符重载

    1static强化练习-仓库进货和出货 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; c ...

  3. c++-变量,this指针,全局函数,成员函数,自定义数组类

    区分变量属于哪个对象 c++对象管理模型初探 C++类对象中的成员变量和成员函数是分开存储的,C中内存四区仍然有效 C++编译器对普通成员函数的内部处理(隐藏this指针) this指针解决函数形参和 ...

  4. C++ 1//设计立方体类 //创建立方体的类 //设计属性和行为 //获取立方体的面积和体积 //分别利用(全局函数 和 成员函数)判断俩个立方体是否相等

    1 //设计立方体类 2 //创建立方体的类 3 //设计属性和行为 4 //获取立方体的面积和体积 5 //分别利用(全局函数 和 成员函数)判断俩个立方体是否相等 6 #include <i ...

  5. 全局函数VS成员函数

    #include <iostream> using namespace std; class Test { public: Test(int a, int b) { this->a ...

  6. C++多态实现(虚函数,成员函数覆盖、隐藏)

    // 1.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using namespace ...

  7. C++(三十三) — 全局函数、成员函数的区别

    区别: (1)全局函数的参数个数,比局部函数要多一个: (2)二者都可,返回元素.返回引用. class test { public: test(int a, int b) { this->a ...

  8. C++之全局函数和成员函数互相转换

    解析:成员函数会用this指针自动隐藏第一个操作数(左操作数) 1.把全局函数转化成成员函数,通过this指针隐藏左操作数. Test add(Test &t1,Test &t2)  ...

  9. C++走向远洋——34(友元函数,成员函数和一般函数的区别)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:youyuan.cpp * 作者:常轩 * 微信公众号:Worl ...

  10. C++虚函数和成员函数内存 this指针问题

    father* p=new son; p->disp(...); 发现有好多人this指针的本质有错误的认识,估计不少人一说起this指针,脑袋立即反应出:那个类里使用的this指针,那么这个指 ...

随机推荐

  1. 怎样理解 Vue 中的计算属性 computed 和 methods ?

    需求: 在 Vue 中, 我们可以像下面这样通过在 引号 或 双花括号 内写 js 表达式去做一些简单运算, 这是可以的, 不过这样写是不直观的, 而且在 html 中 夹杂 一些运算逻辑这种做法其实 ...

  2. 【原创】大叔经验分享(67)spring boot启动报错

    spring boot 启动报错: Caused by: java.lang.IllegalArgumentException: LoggerFactory is not a Logback Logg ...

  3. ZROI2018暑期集训B班训练赛#1解题报告

    版权原因不公布题目信息 A 分析 虽然前一天搞到比较晚,考场上还是比较快的想到了正解,可惜姿势水平低被卡到了64(进入高中不知道考过多少次64了...) 这题有个比较明显且\(naive\)的做法是用 ...

  4. ython实现进程间的通信有Queue,Pipe,Value+Array等,其中Queue实现多个进程间的通信,而Pipe实现两个进程间通信,而Value+Array使用得是共享内存映射文件的方式,所以速度比较快

    1.Queue的使用 from multiprocessing import Queue,Process import os,time,random #添加数据函数 def proc_write(qu ...

  5. CentOS7安装Docker-CE并部署项目

    前言 这是我第一次使用dokcer部署项目,现学现卖.成功之后把所有用到的安装及部署和操作命令做一个总结.如有不足,请指教. 使用的是阿里云服务器.CentOS7版本. Dokcer安装 1.Cent ...

  6. web登录的session、cookie和token

    为什么会有登录这回事 首先这是因为HTTP是无状态的协议,所谓无状态就是在两次请求之间服务器并不会保存任何的数据,相当于你和一个人说一句话之后他就把你忘掉了.所以,登录就是用某种方法让服务器在多次请求 ...

  7. ui组件库

    基于Vue的Quasar Framework 中文网 http://www.quasarchs.com/ quasarframework/quasar: Quasar Frameworkhttps:/ ...

  8. winfrom 操作Excel

    利用Aspose.Cells.dll 操作Excel,内容如下: 1.界面设计: 2.逻辑: using System; using System.Collections.Generic; using ...

  9. deep_learning_Function_ lambda函数详解

    这里总结了关于 Python 中的 lambda 函数的“一个语法,三个特性,四个用法”. 一个语法: 在 Python 中,lambda 函数的语法是唯一的.其形式如下: lambda argume ...

  10. STM32WB RTC

    实时时钟 (RTC) 是一个独立的 BCD 定时器/计数器.RTC 提供一个带可编程闹钟中断的日历时钟以及一个具有中断功能的周期性可编程唤醒标志.RTC 还包含用于管理所有低功耗模式的自动唤醒单元.两 ...