亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

什么是C ++委托?

什么是C ++委托?

C++
qq_笑_17 2019-11-05 10:25:09
C ++中委托的總體思路是什么?它們是什么?它們的用途是什么?我想首先以“黑匣子”的方式來了解它們,但是對這些東西的勇氣有一點了解也是非常有用的。這并不是最純凈或最純凈的C ++,但是我注意到我工作的代碼庫中有大量的C ++。我希望對它們有足夠的了解,因此我可以只使用它們,而不必深入研究嵌套模板的可怕問題。
查看完整描述

3 回答

?
慕工程0101907

TA貢獻1887條經驗 獲得超5個贊

您可以通過多種選擇來實現C ++中的委托。這是我想到的那些。


選項1:函子:


可以通過實現來創建功能對象 operator()


struct Functor

{

     // Normal class/struct members


     int operator()(double d) // Arbitrary return types and parameter list

     {

          return (int) d + 1;

     }

};


// Use:

Functor f;

int i = f(3.14);

選項2:lambda表達式(僅C ++ 11)


// Syntax is roughly: [capture](parameter list) -> return type {block}

// Some shortcuts exist

auto 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

{

     int f1(double d) { }

     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

{

    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)

{

    return func(3.14);

}


查看完整回答
反對 回復 2019-11-05
?
牛魔王的故事

TA貢獻1830條經驗 獲得超3個贊

委托是一個類,它包裝指向對象實例的指針或引用,該對象實例在該對象實例上要被調用的成員方法,并提供觸發該調用的方法。


這是一個例子:


template <class T>

class CCallback

{

public:

    typedef void (T::*fn)( int anArg );


    CCallback(T& trg, fn op)

        : m_rTarget(trg)

        , m_Operation(op)

    {

    }


    void Execute( int in )

    {

        (m_rTarget.*m_Operation)( in );

    }


private:


    CCallback();

    CCallback( const CCallback& );


    T& m_rTarget;

    fn m_Operation;


};


class A

{

public:

    virtual void Fn( int i )

    {

    }

};



int main( int /*argc*/, char * /*argv*/ )

{

    A a;

    CCallback<A> cbk( a, &A::Fn );

    cbk.Execute( 3 );

}

查看完整回答
反對 回復 2019-11-05
?
一只甜甜圈

TA貢獻1836條經驗 獲得超5個贊

對C ++委托實現的需要是對C ++社區的長期困擾。每個C ++程序員都希望擁有它們,因此盡管存在以下事實,他們還是最終使用了它們:

  1. std::function() 使用堆操作(對于嚴重的嵌入式編程是無法實現的)。

  2. 所有其他實現都在或多或少程度上對可移植性或標準一致性做出了讓步(請通過在此處和在代碼項目上檢查各種委托實現進行驗證)。我還沒有看到一個不使用野生的reinterpret_casts的實現,嵌套類“原型”希望產生與用戶傳遞的函數指針大小相同的函數指針,編譯器的技巧如第一個前向聲明,然后是typedef然后再聲明,這次是從另一個班級或類似的黑幕技術繼承下來的。雖然這對于實現此目標的實現者來說是一項巨大的成就,但對于C ++的發展仍然是一個可悲的見證。

  3. 很少有人指出,現在超過3個C ++標準修訂版,未正確處理委托。(或者缺少允許直接實現委托實現的語言功能。)

  4. 通過標準定義C ++ 11 lambda函數的方式(每個lambda具有匿名的不同類型),這種情況僅在某些用例中得到了改善。但是對于在(DLL)庫API中使用委托的用例, lambda 仍然不可用。此處的常用技術是先將lambda打包到std :: function中,然后將其傳遞給API。


查看完整回答
反對 回復 2019-11-05
  • 3 回答
  • 0 關注
  • 686 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號