QT的Event機制里邊,所有的Event都是派生于QEvent類,然后Event派發(fā)的時候都是通過一個函數(shù):event(QEvent*),通過QEvent::Type()獲取到真實的類型,然后使用static_cast轉(zhuǎn)換到實際的類型再派發(fā)到QXXEvent函數(shù)去處理。
這里是利用了CPP的rtii機制,但是為什么沒有用dynamic_cast呢?猜測是為了效率。
但是這樣有一個缺陷,就是當(dāng)Type取到的類型和實際類型不一致的時候沒有rtii的檢測,可能導(dǎo)致類型不匹配,然后崩潰掉。。。
效率是一個原因,但是個人覺得,穩(wěn)定性有限于效率。
即使測試了一下,500000次轉(zhuǎn)換效率也不會太弱,繼承數(shù)深度也不是和效率呈線型關(guān)系的:
class CRoot
{
public:
virtual ~CRoot(){}
};
class CTest : public CRoot
{
public:
virtual void ShowFunctionName()
{
std::cout << __FUNCTION__ << std::endl;
}
};
class CTestEx : public CTest
{
public:
virtual void ShowFunctionName()
{
std::cout << __FUNCTION__ << std::endl;
}
virtual void ShowOnlyForEx()
{
std::cout << __FUNCTION__ << std::endl;
}
};
void Func(CTestEx *pTestEx)
{
pTestEx->ShowOnlyForEx();
}
void Func(CTest *pTest)
{
try
{
CRoot *pRoot = new CTestEx;
boost::timer timerTest;
timerTest.restart();
for (int i = 0; i < 500000; i++)
{
CTestEx *pTextEx = nullptr;
pTextEx = dynamic_cast<CTestEx*>(pRoot);
}
double dTime = timerTest.elapsed();
std::cout << dTime << std::endl;
timerTest.restart();
for (int i = 0; i < 500000; i++)
{
CTest *pText = nullptr;
pText = dynamic_cast<CTest*>(pRoot);
}
dTime = timerTest.elapsed();
std::cout << dTime << std::endl;
//Func(dynamic_cast<CTestEx*>(pRoot));
//Func((CTestEx*)pRoot);
timerTest.restart();
for (int i = 0; i < 500000; i++)
{
CTestEx *pTextEx = nullptr;
pTextEx = static_cast<CTestEx*>(pRoot);
}
dTime = timerTest.elapsed();
std::cout << dTime << std::endl;
}
catch(std::exception& refException)
{
std::cout << refException.what() << std::endl;
}
catch(std::bad_cast)
{
std::cout << __FUNCTION__ << std::endl;
}
catch(...)
{
std::cout << __FUNCTION__ << std::endl;
}
}
void Test()
{
CTest *pTest = new CTest;
Func(pTest);
}
0.031
0.033
0.001
debug模式下運行,感覺這個速度應(yīng)該是能接受的。
向下類型轉(zhuǎn)換的時候使用dynamic_cast應(yīng)該是有必要的,所有咱們就這樣用了吧,,,