IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++:实现委托机制 -> 正文阅读

[C++知识库]C++:实现委托机制

C++ 委托机制

在GUI编程或者基于事件开发的项目中,经常需要使用回调函数. 为了处理这类回调事件, C# 特别提供了关键字delegate来实现.

函数指针回调做法

在传统的C++开发过程中, 为了实现函数回调,一般的做法是将 C++ 的函数指针传给管理者.当有事件触发时,再执行该回调函数.

基于函数指针的回调方式有一下缺点:

  • 对萌新不友好, 上手困难
  • 函数指针操作并不安全,无法在编译阶段检测来

C++11 新特性

为了解决此类问题, C++11 从boost库中借鉴了新特性 functional, 以此为容器存储函数指针,从而优雅的实现回调机制

案例演示:

  • 存储自由函数
  • 存储lambda表达式
  • 存储std::bind 结果 (非常重要)
  • 存储类成员方法和类实例
  • 存储类成员方法和类实例指针
  • 存储结构体方法
#pragma once
#include <functional>
#include <iostream>

void print_num(int i);

inline void print_num(int i)
{
    std::cout << i << '\n';
}

struct PrintNum {
    void operator()(int i) const
    {
        std::cout << i << '\n';
    }
};

struct Foo {
    Foo(int num) : num_(num) {}
    void print_add(int i) const { std::cout << num_ + i << '\n'; }
    int num_;
};

void main();

inline void main()
{
     // store a free function
     std::function<void(int)> f_display = print_num;
     f_display(-9);

     // store a lambda
     std::function<void()> f_display_42 = []() { print_num(42); };
     f_display_42();

     //store the result of a call to std::bind
     std::function<void()> f_display_31337 = std::bind(print_num, 31337);
     f_display_31337();

     // //store a call to a member function
     //std::function<void(const Foo&, int)> f_add_display = &Foo::print_add;
     const Foo foo(314159);
     //f_add_display(foo, 1);

     //store a call to a data member accessor
     //std::function<int(Foo const&)> f_num = &Foo::num_;
     //std::cout << "num_: " << f_num(foo) << '\n';

     // store a call to a member function and object
     using std::placeholders::_1;
     std::function<void(int)> f_add_display2 = std::bind(&Foo::print_add, foo, _1);
     f_add_display2(2);

     // store a call to a member function and object ptr
     std::function<void(int)> f_add_display3 = std::bind(&Foo::print_add, &foo, _1);
     f_add_display3(3);

     // store a call to a function object
     std::function<void(int)> f_display_obj = PrintNum();
     f_display_obj(18);
}

委托机制实现

#pragma once
#include <functional>
#include <iostream>
#include <vector>

using namespace std;
class IObj
{
public:
	virtual int callback(string t_data) = 0;
};


class AppleObj : public IObj
{

public:
	virtual int callback(string t_data) final
	{
		cout << "this is  appleobj : " << endl;
		return 0;
	}
};

class BananaObj : public IObj
{
public:
	virtual int callback(string t_data) final
	{
		cout << "this is  banana object: " << endl;
		return 1;
	}
};


class DeleManager
{
public:
	DeleManager() {};
	~DeleManager() {};
	void addObj(function<int(string)> t_dele)
	{
		_dele_list.push_back(t_dele);
	}
	void notify(string t_msg)
	{
		if (_dele_list.empty())
		{
			cout << "list is empty " << endl;
			return;
		}

		for (auto itor : _dele_list)
		{
			itor(t_msg);
		}
	}

private:
	vector <function<int(string)>> _dele_list;
};

void main()
{
	DeleManager i_manager;
	AppleObj i_apple;
	BananaObj i_banana;
	using std::placeholders::_1;
	std::function<int(string)> i_dele_apple = std::bind(&AppleObj::callback, i_apple, _1);
	i_manager.addObj(i_dele_apple);
	std::function<int(string)> i_dele_banana = std::bind(&BananaObj::callback, i_banana, _1);
	i_manager.addObj(i_dele_banana);
	i_manager.notify("happy middle september day");
}

windows消息回调

在windows GUI 开发过程中, 一般通过 postmessage 来完成消息回调,触发GUI执行对应的操作. 这种方式简单易行,对萌新友好,且具备跨线程操作的功能. 但是postmessage 也有自身的缺陷:

  • 过渡依赖windows消息机制
  • 回调传参可定制程度低

总结

为了解决GUI 跨线程操作界面的导致主线程崩溃的情况, C++ 11 终于推出了自己的thread 类
thread 类提供detach() 的方法, 让worker线程也具备了操作GUI的能力.
在GUI开发中, 通过使用functionthread等C++ 11 新特性,能够更便捷的开发出高质量的程序, 同时回避开发过程中的问题。

转:https://www.jianshu.com/p/c2c34014b739

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 18:45:50  更:2022-08-19 18:47:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/10 23:14:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码