C++中如何实现回调的方法示例

C++中实现回调的方法有多种,下面介绍两种常见的实现方式。

方式一:函数指针

通过函数指针实现回调,需要定义一个函数指针类型,将回调函数与函数指针进行绑定,然后在合适的时机调用函数指针即可。

示例1

定义一个函数指针类型,函数原型为:

typedef void (*MyCallbackFunc) (int arg1, int arg2);

其中,第一个参数表示回调函数的返回值类型,第二个参数表示回调函数的参数个数及类型。

定义一个类,成员变量为函数指针类型,成员函数用于设置和触发回调函数。

class MyClass {
public:
    void SetCallback(MyCallbackFunc callback) {
        _callback = callback;
    }

    void DoSomething() {
        // 判断回调函数是否为空指针
        if (_callback != nullptr) {
            // 调用回调函数
            _callback(10, 20);
        }
    }

private:
    MyCallbackFunc _callback; // 函数指针类型成员变量
};

客户端需要实现一个回调函数,并将其与类的函数指针绑定。示例代码如下:

void MyCallback(int arg1, int arg2) {
    // do something
}

int main() {
    MyClass myClass;
    myClass.SetCallback(MyCallback);
    myClass.DoSomething();
    return 0;
}

在main函数中生成一个MyClass对象,调用SetCallback函数将MyCallback函数与函数指针绑定,然后调用DoSomething函数触发回调函数。

示例2

使用STL中的函数对象(function object)代替函数指针实现回调。function object 是一个可调用的对象,可以表示函数指针、lambda表达式、成员函数指针等。

定义一个函数对象类型,函数原型与上一个示例中的函数指针类型相同。

using MyCallbackFunc = std::function<void(int, int)>;

使用STL中的std::function模板类代替函数指针类型。

重写MyClass类,将函数指针类型的成员变量改为函数对象类型。

class MyClass {
public:
    void SetCallback(MyCallbackFunc callback) {
        _callback = callback;
    }

    void DoSomething() {
        // 判断回调函数是否为空
        if (_callback) {
            _callback(10, 20);
        }
    }

private:
    MyCallbackFunc _callback;
};

客户端代码与示例1中的相同。

方式二:虚函数

使用虚函数也可以实现回调。

示例1

定义一个基类,将回调函数声明为虚函数。

class MyBaseClass {
public:
    virtual void MyCallback(int arg1, int arg2) { }
};

派生一个子类MyClass,在其内部实现回调函数。

class MyClass : public MyBaseClass {
public:
    void DoSomething() {
        // ...

        // 判断回调函数是否为空
        if (_callback) {
            _callback(10, 20);
        }

        // ...
    }

private:
    void MyCallback(int arg1, int arg2) override {
        // do something
    }
};

在MyClass类中调用MyCallback函数即可触发回调。

示例2

使用虚函数时,可以使用接口(interface)定义回调函数,客户端需要实现接口中的回调函数。

定义一个接口,包含所有需要实现的回调函数。

class IMyCallback {
public:
    virtual ~IMyCallback() { }
    virtual void MyCallback(int arg1, int arg2) { } // 回调函数声明
};

重新定义MyClass类,将回调函数类型改为IMyCallback接口。

class MyClass {
public:
    void SetCallback(IMyCallback* callback) {
        _callback = callback;
    }

    void DoSomething() {
        // ...

        if (_callback) {
            _callback->MyCallback(10, 20);
        }

        // ...
    }

private:
    IMyCallback* _callback;
};

客户端需要实现MyCallback函数,代码如下:

class MyCallbackImpl : public IMyCallback {
public:
    void MyCallback(int arg1, int arg2) override {
        // do something
    }
};

int main() {
    MyClass myClass;
    MyCallbackImpl callbackImpl;
    myClass.SetCallback(&callbackImpl);
    myClass.DoSomething();
    return 0;
}

在main函数中生成一个MyClass对象,同时生成一个MyCallbackImpl对象实现接口中的回调函数,然后调用SetCallback函数将MyCallbackImpl对象的指针作为参数传入,最后调用DoSomething函数触发回调函数。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++中如何实现回调的方法示例 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • Python hashlib和hmac模块使用方法解析

    Python hashlib和hmac模块使用方法解析 简介 哈希算法(HASH),又称散列算法,是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。当输入的消息内容一样时,计算出来的消息摘要也相同,不同输入的消息内容计算出来的消息摘要也不同。哈希算法广泛应用于数字签名、消息认证码、随机映射等领域。 Python的hashlib模块提供了多种哈希算法的…

    C 2023年5月23日
    00
  • 用C语言操作MySQL数据库的通用方法

    使用C语言操作MySQL数据库,需要借助MySQL提供的C API。下面将介绍MySQL数据库的C API使用的基本步骤和示例代码。 步骤 引入MySQL连接库头文件 在代码中引入MySQL连接库的头文件:#include <mysql.h> 初始化数据库连接 在代码中使用mysql_init()函数初始化一个MYSQL对象,并使用mysql_r…

    C 2023年5月22日
    00
  • C语言中extern详细用法解析

    请看下面的完整攻略。 C语言中extern详细用法解析 什么是extern? extern是C语言中的一个关键字,它的作用是用来声明一个变量或者函数的定义是在别的文件中,需要在本文件中进行引用。 extern的语法格式 在C语言中,extern语法格式如下所示: extern data_type variable_name; extern return_ty…

    C 2023年5月23日
    00
  • C语言简明讲解操作符++和–的使用方法

    C语言简明讲解操作符++和–的使用方法 操作符++和–的基本概念 操作符++和–是C语言中的两种自增、自减操作符。它们作用于一个变量,可以将该变量的值自增1或自减1。 操作符++:将变量的值自增1,等同于var = var + 1。 操作符–:将变量的值自减1,等同于var = var – 1。 这两个操作符都可以在变量前面或后面使用,从而分别产生前…

    C 2023年5月23日
    00
  • C++控制台绘图头文件实例代码

    下面是对“C++控制台绘图头文件实例代码”的完整攻略: 1. 简介 在C++的控制台程序中,通过使用图形化绘图头文件,可以在控制台中绘制出各种图形。 2. 下载 在使用绘图头文件前,需要下载对应的库文件。 目前比较流行的库包括: graphics.h:Borland C++ 5.02自带的,不建议使用。 conio.h:Turbo C自带的,也不建议使用。 …

    C 2023年5月24日
    00
  • C++实现管理系统的示例代码

    C++实现管理系统的示例代码包含以下步骤: 设计系统需求和功能 在开始写代码之前需要明确系统的需求和功能,这可以帮助我们更好地组织代码。例如,我们可以列出以下需求和功能: 系统应该能够添加、查看、修改和删除学生信息 学生信息应该包括姓名、年龄、性别等基本信息 系统应该能够按姓名、年龄、性别等信息对学生信息进行排序 系统应该能够将学生信息保存到文件中,并能够从…

    C 2023年5月23日
    00
  • C语言二维数组

    讲解“C语言二维数组”的完整使用攻略。 1. 什么是C语言二维数组? C语言二维数组是一种数组类型,它与一维数组不同,它是由多个一维数组组合而成。一维数组可以理解为一列,而二维数组可以理解为一个表格,它由多行多列组成。 2. 声明C语言二维数组 C语言二维数组的声明格式如下: type array_name[row][col]; 其中,type可以是任何基本…

    C 2023年5月9日
    00
  • Java详细讲解异常Exception的处理

    Java详细讲解异常Exception的处理 什么是异常Exception 异常(Exception)指的是程序运行过程中不正常(错误)的情况,例如输入输出错误、计算错误、网络连接中断等情况。一般来说,出现异常会导致程序停止运行。 在Java中,异常被抛出后可以被程序处理,以免程序崩溃。Java中的异常分为两种类型:受检异常(Checked Exceptio…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部