C++中回调函数(CallBack)的用法分析_C 语言

本文实例分析了C++中回调函数(CallBack)的用法。分享给大家供大家参考。具体分析如下:

如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就不能通过。
其错误是普通的C++成员函数都隐含了一个传递函数作为参数,亦即“this”指针,C++通过传递this指针给其成员函数从而实现程序函数可以访问C++的数据成员。这也可以理解为什么C++类的多个实例可以共享成员函数却-有不同的数据成员。由于this指针的作用,使得将一个CALL-BACK型的成员函数作为回调函数安装时就会因为隐含的this指针使得函数参数个数不匹配,从而导致回调函数安装失败。要解决这一问题的关键就是不让this指针起作用,通过采用以下两种典型技术可以解决在C++中使用回调函数所遇到的问题。这种方法具有通用性,适合于任何C++。
  
1).   不使用成员函数,为了访问类的成员变量,可以使用友元操作符(friend),在C++中将该函数说明为类的友元即可。

2).   使用静态成员函数,静态成员函数不使用this指针作为隐含参数,这样就可以作为回调函数了。静态成员函数具有两大特点:其一,可以在没有类实例的情况下使用;其二,只能访问静态成员变量和静态成员函数,不能访问非静态成员变量和非静态成员函数。由于在C++中使用类成员函数作为回调函数的目的就是为了访问所有的成员变量和成员函数,如果做不到这一点将不具有实际意义。解决的办法也很简单,就是使用一个静态类指针作为类成员,通过在类创建时初始化该静态指针,如pThis=this,然后在回调函数中通过该静态指针就可以访问所有成员变量和成员函数了。

这种处理办法适用于只有一个类实例的情况,因为多个类实例将共享静态类成员和静态成员函数,这就导致静态指针指向最后创建的类实例。为了避免这种情况,可以使用回调函数的一个参数来传递this指针,从而实现数据成员共享。这种方法稍稍麻烦,这里就不再赘述。
例子:

复制代码 代码如下:

#include "stdafx.h" 
#include <iostream> 
#include <assert.h> 
using namespace std; 
 
class Test 

public: 
    friend void callBackFun(void){ cout << "CallBack Function!";} //因为callBackFun默认有一个const Test* 的指针 
}; 
 
typedef void (*FPtr)(void); 
void Fun(FPtr ptr) 

    ptr(); 

int main(void) 

    Fun(callBackFun);  
 
    return 0; 
}

希望本文所述对大家的C++程序设计有所帮助。

时间: 2024-10-17 08:10:36

C++中回调函数(CallBack)的用法分析_C 语言的相关文章

深入VC回调函数的使用详解_C 语言

回调函数说白了就是事件响应程序,Windows的每个消息可以理解为一个事件,事件的响应代码要由用户自己来定义.用户定义了事件响应的代码,但还要Windows知道这段代码的位置(要不然Windows就不知道如何去调用,这也没有用),于是用户需要将回调函数的指针告诉Windows,最典型的例子是在窗口类的结构(WNDCLASS)中给lpfnWndProc分量赋回调函数指针值. 回调函数的参数格式是由回调函数的调用者(一般是Windows)来定义的,而回调函数的实现者必须遵循这种格式.Windows程

C语言中的函数指针基础学习教程_C 语言

顾名思义,函数指针就是函数的指针.它是一个指针,指向一个函数.看例子: A) char * (*fun1)(char * p1,char * p2); B) char * *fun2(char * p1,char * p2); C) char * fun3(char * p1,char * p2); 看看上面三个表达式分别是什么意思? C)这很容易,fun3是函数名,p1,p2是参数,其类型为char *型,函数的返回值为char *类型. B) 也很简单,与C)表达式相比,唯一不同的就是函数的

C/C++常用函数易错点分析_C 语言

本文简单分析了C/C++中常用函数的易错点,包括memset.sizeof.getchar等函数.分享给大家供大家参考之用.具体分析如下: 1.memset #include <string.h> void* memset( void* buffer, int ch, size_t count ); 将内存中buffer的前count个字节的内容全部设置为ch指定的ASCII值.经常用来初始化数组.复制时以字节为单位,如果buffer是int long,或者其他类型的指针时,需要注意不一定为数

c++中inline的用法分析_C 语言

在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联. inline int min(int first, int secend) {/****/};inline函数对编译器而言必须是可见的,以便它能够在调用点内展开该函数.与非inline函数不同的是,inline函数必须在调用该函数的每个文本文件中定义.当然,对于同一程序的不同文件,如果inline函数出现的话,其定义必须相同.对于由两个文件compute.C和draw.C构成的程序来说,程序员不能定义这样的min(

关于C/C++中typedef的定义与用法总结_C 语言

在C还是C++代码中,typedef都使用的很多,在C代码中尤其是多.typedef与#define有些相似,其实是不同的,特别是在一些复杂的用法上,看了网上一些C/C++的学习者的博客,其中有一篇关于typedef的总结还是很不错,由于总结的很好,我就不加修改的引用过来了,加上自己的一个分析. 基本定义: typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等). 在编程中使用typedef目的

C++虚函数的实现机制分析_C 语言

本文针对C++的虚函数的实现机制进行较为深入的分析,具体如下: 1.简单地说,虚函数是通过虚函数表实现的.那么,什么是虚函数表呢? 事实上,如果一个类中含有虚函数,则系统会为这个类分配一个指针成员指向一张虚函数表(vtbl),表中每一项指向一个虚函数的地址,实现上就是一个函数指针的数组. 例如下面这个例子: class Parent { public: virtual void foo1() { } virtual void foo1() { } void foo1(); }; class Ch

C++编程中的const关键字常见用法总结_C 语言

1.定义常量(1)const修饰变量,以下两种定义形式在本质上是一样的.它的含义是:const修饰的类型为TYPE的变量value是不可变的. TYPE const ValueName = value; const TYPE ValueName = value; (2)将const改为外部连接,作用于扩大至全局,编译时会分配内存,并且可以不进行初始化,仅仅作为声明,编译器认为在程序其他地方进行了定义. extend const int ValueName = value; 2.指针使用CONST

C++中fstream,ifstream及ofstream用法浅析_C 语言

c++中有个类叫做fstream,可以实现打开一个文件作为流.创建一个对象,然后调用该对象的open函数,其主要有两个参数,第一个参数是字符串,表示文件的地址,第二个参数是代开方式,如: fstream fin("a.txt",ios::in); if(fin) { cout<<"opened"<<endl; fin.close(); } else { cout<<"not exists"<<end

C++中sprintf()函数的使用详解_C 语言

在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望.由于sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出.这也导致sprintf 比printf 有用得多.sprintf 是个变参函数,定义如下:int sprintf( char *buffer, const char *format [, argument] ... );除了前两个参数类型固定外,后面可以接任意多个参数.而它的精华,显然就在第二个参