QT的Event机制里边,所有的Event都是派生于QEvent类,然后Event派发的时候都是通过一个函数:event(QEvent*),通过QEvent::Type()获取到真实的类型,然后使用static_cast转换到实际的类型再派发到QXXEvent函数去处理。
这里是利用了CPP的rtii机制,但是为什么没有用dynamic_cast呢?猜测是为了效率。
但是这样有一个缺陷,就是当Type取到的类型和实际类型不一致的时候没有rtii的检测,可能导致类型不匹配,然后崩溃掉。。。
效率是一个原因,但是个人觉得,稳定性有限于效率。
即使测试了一下,500000次转换效率也不会太弱,继承数深度也不是和效率呈线型关系的:
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模式下运行,感觉这个速度应该是能接受的。
向下类型转换的时候使用dynamic_cast应该是有必要的,所有咱们就这样用了吧,,,