0
這是一個簡單的委託類,只適用於格式無效類類別:: MethodType(的inputType &)的方法,但可以很容易地擴展到更通用的功能,不是簡單地顯示增加因爲它會太大。C++:性能上非模板委託類
class Delegate
{
public:
Delegate(void) : Object(NULL), Argument(NULL) { }
virtual ~Delegate(void) { }
template <class ClassType, class InputType, void (ClassType::*MethodType)(InputType)>
void Create(ClassType* SetObject, void* SetArgument = NULL)
{
Object = SetObject;
Argument = SetArgument;
StaticCall = &CallMethod<ClassType, InputType, MethodType>;
}
template <class InputType>
inline void operator()(InputType InputValue) const
{
(*StaticCall)(Object, static_cast<void*>(InputValue));
}
inline void operator()(void) const
{
(*StaticCall)(Object, Argument);
}
protected:
typedef void (*FunctionCallType)(void*, void*);
void* Object;
void* Argument;
FunctionCallType StaticCall;
private:
template <class ClassType, class InputType, void (ClassType::*MethodType)(InputType)>
static inline void CallMethod(void* SetObject, void* PassArgument)
{
(static_cast<ClassType*>(SetObject)->*MethodType)(static_cast<InputType>(PassArgument));
}
};
它是靈活的,可用於游泳池回調類,但有一個問題,我與它是不是一個虛擬的(在大載體中使用時,就像我打算或更慢),到目前爲止它看齊如果它被用作基類,則調用它。我正在尋找任何關於如何提高性能的建議,因爲我已經沒有想法,即使它影響功能。
我用(與-O3)最簡單的性能測量代碼爲:
class VirtualBase
{
public:
virtual void TestCall(int* Data) {}
};
class VirtualTest : public VirtualBase
{
public:
VirtualTest() : Value(0) {}
void TestCall(int* Data)
{
Value += *Data;
}
private:
int Value;
};
class DelTest : public Delegate
{
public:
DelTest() : Value(0)
{
Create<DelTest, int*, &DelTest::TestCall>(this);
}
void TestCall(int* Data)
{
Value += *Data;
}
private:
int Value;
};
int main(int argc, char **argv)
{
clock_t start;
int Value = 1;
VirtualBase* NewBase = new VirtualTest;
start = clock();
for(size_t Index = 0; Index < 1000000000; ++Index)
{
NewBase->TestCall(&Value);
}
delete NewBase;
std::cout << ((std::clock() - start)/(double)CLOCKS_PER_SEC) << std::endl;
Delegate* NewDBase = new DelTest;
start = clock();
for(size_t Index = 0; Index < 1000000000; ++Index)
{
NewDBase->operator()(&Value);
}
delete NewDBase;
std::cout << ((std::clock() - start)/(double)CLOCKS_PER_SEC) << std::endl;
return 0;
}
我要指出,我希望全班同學留下非模板,因爲它使得使用回調類難爲易在單個向量中迭代。
你檢查[該難以置信的快C++委託(http://www.codeproject.com/Articles/11015/The-Impossibly-Fast-C-Delegates)?它與你的非常相似,但一個區別是成員函數指針是編譯時常量,所以你不需要將它作爲運行時參數傳遞。 – iavr
我會刪除'參數'。這是'std :: bind'的一個工作,在一個類中混合兩個不同的功能並不是一個好設計 - 委託本身足夠複雜。另外,對於一般情況,C++ 11中的可變參數實現不會比1參數版本長很多。 – iavr
你試過std :: function嗎? –