什么是C ++委托?

C ++中委托的总体思路是什么?它们是什么?它们的用途是什么?


我想首先以“黑匣子”的方式来了解它们,但是对这些东西的勇气有一点了解也是非常有用的。


这并不是最纯净或最纯净的C ++,但是我注意到我工作的代码库中有大量的C ++。我希望对它们有足够的了解,因此我可以只使用它们,而不必深入研究嵌套模板的可怕问题。


qq_笑_17
浏览 642回答 3
3回答

慕工程0101907

您可以通过多种选择来实现C ++中的委托。这是我想到的那些。选项1:函子:可以通过实现来创建功能对象 operator()struct Functor{&nbsp; &nbsp; &nbsp;// Normal class/struct members&nbsp; &nbsp; &nbsp;int operator()(double d) // Arbitrary return types and parameter list&nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (int) d + 1;&nbsp; &nbsp; &nbsp;}};// Use:Functor f;int i = f(3.14);选项2:lambda表达式(仅C ++ 11)// Syntax is roughly: [capture](parameter list) -> return type {block}// Some shortcuts existauto func = [](int i) -> double { return 2*i/1.15; };double d = func(1);选项3:函数指针int f(double d) { ... }typedef int (*MyFuncT) (double d);MyFuncT fp = &f;int a = fp(3.14);选项4:指向成员函数的指针(最快的解决方案)请参见Fast C ++ Delegate(在The Code Project上)。struct DelegateList{&nbsp; &nbsp; &nbsp;int f1(double d) { }&nbsp; &nbsp; &nbsp;int f2(double d) { }};typedef int (DelegateList::* DelegateType)(double d);DelegateType d = &DelegateList::f1;DelegateList list;int a = (list.*d)(3.14);选项5:std :: function(或者boost::function如果您的标准库不支持它)。它比较慢,但是最灵活。#include <functional>std::function<int(double)> f = [can be set to about anything in this answer]// Usually more useful as a parameter to another functions选项6:绑定(使用std :: bind)允许预先设置一些参数,例如方便调用成员函数。struct MyClass{&nbsp; &nbsp; int DoStuff(double d); // actually a DoStuff(MyClass* this, double d)};std::function<int(double d)> f = std::bind(&MyClass::DoStuff, this, std::placeholders::_1);// auto f = std::bind(...); in C++11选项7:模板接受与参数列表匹配的任何内容。template <class FunctionT>int DoSomething(FunctionT func){&nbsp; &nbsp; return func(3.14);}

牛魔王的故事

委托是一个类,它包装指向对象实例的指针或引用,该对象实例在该对象实例上要被调用的成员方法,并提供触发该调用的方法。这是一个例子:template <class T>class CCallback{public:&nbsp; &nbsp; typedef void (T::*fn)( int anArg );&nbsp; &nbsp; CCallback(T& trg, fn op)&nbsp; &nbsp; &nbsp; &nbsp; : m_rTarget(trg)&nbsp; &nbsp; &nbsp; &nbsp; , m_Operation(op)&nbsp; &nbsp; {&nbsp; &nbsp; }&nbsp; &nbsp; void Execute( int in )&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; (m_rTarget.*m_Operation)( in );&nbsp; &nbsp; }private:&nbsp; &nbsp; CCallback();&nbsp; &nbsp; CCallback( const CCallback& );&nbsp; &nbsp; T& m_rTarget;&nbsp; &nbsp; fn m_Operation;};class A{public:&nbsp; &nbsp; virtual void Fn( int i )&nbsp; &nbsp; {&nbsp; &nbsp; }};int main( int /*argc*/, char * /*argv*/ ){&nbsp; &nbsp; A a;&nbsp; &nbsp; CCallback<A> cbk( a, &A::Fn );&nbsp; &nbsp; cbk.Execute( 3 );}

一只甜甜圈

对C ++委托实现的需要是对C ++社区的长期困扰。每个C ++程序员都希望拥有它们,因此尽管存在以下事实,他们还是最终使用了它们:std::function()&nbsp;使用堆操作(对于严重的嵌入式编程是无法实现的)。所有其他实现都在或多或少程度上对可移植性或标准一致性做出了让步(请通过在此处和在代码项目上检查各种委托实现进行验证)。我还没有看到一个不使用野生的reinterpret_casts的实现,嵌套类“原型”希望产生与用户传递的函数指针大小相同的函数指针,编译器的技巧如第一个前向声明,然后是typedef然后再声明,这次是从另一个班级或类似的黑幕技术继承下来的。虽然这对于实现此目标的实现者来说是一项巨大的成就,但对于C ++的发展仍然是一个可悲的见证。很少有人指出,现在超过3个C ++标准修订版,未正确处理委托。(或者缺少允许直接实现委托实现的语言功能。)通过标准定义C ++ 11 lambda函数的方式(每个lambda具有匿名的不同类型),这种情况仅在某些用例中得到了改善。但是对于在(DLL)库API中使用委托的用例,仅&nbsp;lambda&nbsp;仍然不可用。此处的常用技术是先将lambda打包到std :: function中,然后将其传递给API。
打开App,查看更多内容
随时随地看视频慕课网APP