C++ 之 委托模式
2022/1/17 17:07:21
本文主要是介绍C++ 之 委托模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 成员函数指针
- 使用模板类
- 使用多态
原文地址
成员函数指针
class A{ public: void Func(int){ std::cout << "I am in A" << std::endl; } };
void (A::*pFunc)(int) = &A::Func;
使用模板类
template <typename T> class DelegateHandler{ public: DelegateHandler(T *pT, void (T::*pFunc)(int)) : m_pT(pT), m_pFunc(pFunc){} void Invoke(int value){ (m_pT->*m_pFunc)(value); } private: T *m_pT; void (T::*m_pFunc)(int); };
A a; DelegateHandler<A> dha(&a, &A::Func); dha.Invoke(3); B b; DelegateHandler<B> dhb(&b, &B::Method); //B::Method的声明与A::Func类似 dhb.Invoke(4);
到这里产生了一个问题:如果希望调用的目标是非成员函数,怎么办?上面的类模板无法调用非成员函数,不过使用模板偏特化就可以解决这个问题:
template<> class DelegateHandler<void>{ //void代替前面的类型T,表示类模板没有参数 public: DelegateHandler(void(*pFunc)(int)) : m_pFunc(pFunc){} void Invoke(int value){ (*m_pFunc)(value); } private: void(*m_pFunc)(int); };
非成员函数的使用方法:
void NonmemberFunc(int param){ std::cout << "I am in NonmemberFunc!" << std::endl; } DelegateHandler<void> dhf(NonmemberFunc); dhf.Invoke(5);
使用多态
对于单目标的委托来说,使用上面的代码或许就已经足够了。但是我的目的当然不止于此,我想要的是多目标的委托。多目标委托其实就是一个容器,在这个容器里可以存放多个对象(这里的对象指的是委托对象,不是A也不是B),当调用委托的时候依次调用每个对象。容器里的对象应该都是相同的类型,这样才能够放到强类型的容器中;而且委托调用方不应该知道具体的调用目标是什么,所以这些对象也应该要隐藏具体的细节。遗憾的是,上一步中实现的类模板都不具备这些能力,DelegateHandler和DelegateHandler是不同的类型,不能放到同一个容器中,调用方要调用它们也必须知道调用的目标是什么类型。
解决这个问题的方法就是使用多态,令所有的委托目标类都继承一个公共的接口,调用方只通过这个接口来进行调用,这样就不必知道每个目标(这里的目标还是指的委托)具体的类型。下面就是该接口的定义
class IDelegateHandler{ public: virtual ~IDelegateHandler(){} virtual void Invoke(int) = 0; };
然后令DelegateHandler继承该接口:
template<typename T> class DelegateHandler : public IDelegateHandler{ public: DelegateHandler(T *pT, void (T::*pFunc)(int)) : m_pT(pT), m_pFunc(pFunc){} virtual void Invoke(int value) override { (m_pT->*m_pFunc)(value); } private: T *m_pT; void (T::*m_pFunc)(int); }; template<> class DelegateHandler<void> : public IDelegateHandler{ public: DelegateHandler(void (*pFunc)(int)) : m_pFunc(pFunc){} virtual void Invoke(int value) override{ (*m_pFunc)(value); } private: void (*m_pFunc)(int); };
现在可以将各种类型的DelegateHandler放到同一个容器中,并使用同样的方式来调用了:
A a; B b; DelegateHandler<A> dha(&a, &A::*Func); DelegateHandler<B> dhb(&b, &B::*Method); DelegateHandler<void> dhf(NonmemberFunc); std::vector<IDelegateHandler*> handlers; handlers.push_back(&dha); handlers.push_back(&dhb); handlers.push_back(&dhf); //这里的auto等于std::vector<IDelegateHandler*>::const_iterator for (auto itor = handlers.cbegin(); itor != handlers.cend(); ++itor){ (*itor)->Invoke(7); }
这篇关于C++ 之 委托模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享