3 回答

TA貢獻(xiàn)1887條經(jīng)驗(yàn) 獲得超5個(gè)贊
您可以通過(guò)多種選擇來(lái)實(shí)現(xiàn)C ++中的委托。這是我想到的那些。
選項(xiàng)1:函子:
可以通過(guò)實(shí)現(xiàn)來(lái)創(chuàng)建功能對(duì)象 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);
選項(xiàng)2:lambda表達(dá)式(僅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);
選項(xiàng)3:函數(shù)指針
int f(double d) { ... }
typedef int (*MyFuncT) (double d);
MyFuncT fp = &f;
int a = fp(3.14);
選項(xiàng)4:指向成員函數(shù)的指針(最快的解決方案)
請(qǐng)參見(jiàn)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);
選項(xiàng)5:std :: function
(或者boost::function如果您的標(biāo)準(zhǔn)庫(kù)不支持它)。它比較慢,但是最靈活。
#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
選項(xiàng)6:綁定(使用std :: bind)
允許預(yù)先設(shè)置一些參數(shù),例如方便調(diào)用成員函數(shù)。
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
選項(xiàng)7:模板
接受與參數(shù)列表匹配的任何內(nèi)容。
template <class FunctionT>
int DoSomething(FunctionT func)
{
return func(3.14);
}

TA貢獻(xiàn)1830條經(jīng)驗(yàn) 獲得超3個(gè)贊
委托是一個(gè)類(lèi),它包裝指向?qū)ο髮?shí)例的指針或引用,該對(duì)象實(shí)例在該對(duì)象實(shí)例上要被調(diào)用的成員方法,并提供觸發(fā)該調(diào)用的方法。
這是一個(gè)例子:
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 );
}

TA貢獻(xiàn)1836條經(jīng)驗(yàn) 獲得超5個(gè)贊
對(duì)C ++委托實(shí)現(xiàn)的需要是對(duì)C ++社區(qū)的長(zhǎng)期困擾。每個(gè)C ++程序員都希望擁有它們,因此盡管存在以下事實(shí),他們還是最終使用了它們:
std::function()
使用堆操作(對(duì)于嚴(yán)重的嵌入式編程是無(wú)法實(shí)現(xiàn)的)。所有其他實(shí)現(xiàn)都在或多或少程度上對(duì)可移植性或標(biāo)準(zhǔn)一致性做出了讓步(請(qǐng)通過(guò)在此處和在代碼項(xiàng)目上檢查各種委托實(shí)現(xiàn)進(jìn)行驗(yàn)證)。我還沒(méi)有看到一個(gè)不使用野生的reinterpret_casts的實(shí)現(xiàn),嵌套類(lèi)“原型”希望產(chǎn)生與用戶(hù)傳遞的函數(shù)指針大小相同的函數(shù)指針,編譯器的技巧如第一個(gè)前向聲明,然后是typedef然后再聲明,這次是從另一個(gè)班級(jí)或類(lèi)似的黑幕技術(shù)繼承下來(lái)的。雖然這對(duì)于實(shí)現(xiàn)此目標(biāo)的實(shí)現(xiàn)者來(lái)說(shuō)是一項(xiàng)巨大的成就,但對(duì)于C ++的發(fā)展仍然是一個(gè)可悲的見(jiàn)證。
很少有人指出,現(xiàn)在超過(guò)3個(gè)C ++標(biāo)準(zhǔn)修訂版,未正確處理委托。(或者缺少允許直接實(shí)現(xiàn)委托實(shí)現(xiàn)的語(yǔ)言功能。)
通過(guò)標(biāo)準(zhǔn)定義C ++ 11 lambda函數(shù)的方式(每個(gè)lambda具有匿名的不同類(lèi)型),這種情況僅在某些用例中得到了改善。但是對(duì)于在(DLL)庫(kù)API中使用委托的用例,僅 lambda 仍然不可用。此處的常用技術(shù)是先將lambda打包到std :: function中,然后將其傳遞給API。
- 3 回答
- 0 關(guān)注
- 689 瀏覽
添加回答
舉報(bào)