C++ (Qt)void test_virtual_fun(ListBase &l) { Iter it = l.begin(); for(; it != l.end(); ++it) { if ((*it)->type() == TYPE_F) { // Один вызов виртуального метода DerivedF *obj = static_cast<DerivedF*>(*it); // Пренебрегаем издержками на вызов static_cast obj->myFunc(); // один вызов не виртуального метода! } }}
4) Спорно/проблематично кто там больше "затуманивает". Часто текст превращается в демонстрацию знания C++ и автор озабочен не содержательной частью а лишь той самой "формальной грамотностью". Продравшись через все навороты обнаруживается, что дела-то "пшик", ф-циональность слаба. А бывает и наоборот
C++ (Qt)Base * base = *it;int sum = 0;for (size_t i = 0; i < NUM_CALL; ++i) sum += base->typeVirtual();
C++ (Qt)Base * base = *it;int sum = 0;for (size_t i = 0; i < NUM_CALL; ++i) { DerivedF * derF = dynamic_cast <DerivedF *> (base); if (derF) sum += derF->typeNonVirtial(); else { DerivedInt * derInt = dynamic_cast <DerivedInt *> (base); if (derInt) sum += derInt->typeNonVirtial(); }}
C++ (Qt)void TestVirtual( const QVector <CBase *> & vec ){ QTime begT = QTime::currentTime(); int sum = 0; for (int i = 0; i < vec.size(); ++i) { CBase * base = vec[i]; for (size_t j = 0; j < NUM_CALL; ++j) sum += base->typeVirtual(); // Один вызов виртуальной функции } int msecs = begT.msecsTo(QTime::currentTime()); qDebug() << "TestVirtual time(sec): " << (msecs / 1000.0f) << "sum =" << sum;} void TestNonVirtual( const QVector <CBase *> & vec ){ QTime begT = QTime::currentTime(); int sum = 0; for (int i = 0; i < vec.size(); ++i) { CBase * base = vec[i]; for (size_t j = 0; j < NUM_CALL; ++j) { CBaseA * a = dynamic_cast<CBaseA *> (base); // Раз: вызов dynamic_cast if (a) sum += a->typeNonVirtual(); // + Нужно учитывать дополнительное время от вызова обычной функции else { CBaseB * b = dynamic_cast<CBaseB *> (base); // Два: Вызов dynamic_cast if (b) sum += b->typeNonVirtual(); // Не учитываем добавочное время от этой операции? } } } int msecs = begT.msecsTo(QTime::currentTime()); qDebug() << "TestNonVirtual time(sec): " << (msecs / 1000.0f) << "sum =" << sum;}
C++ (Qt)dynamic_cast: (1.56, 1.54, 1.54) sec; <t> = 1.547 secvirtual_fun: (1.49, 1.49, 1.48) sec; <t> = 1.487 sec
C++ (Qt)void TestVirtual( const QVector <CBase *> & vec ){ QTime begT = QTime::currentTime(); int sum = 0; for (int i = 0; i < vec.size(); ++i) { CBase * base = vec[i]; for (size_t j = 0; j < NUM_CALL; ++j) sum += base->typeVirtual(); // Без изменений } int msecs = begT.msecsTo(QTime::currentTime()); qDebug() << "TestVirtual time(sec): " << (msecs / 1000.0f) << "sum =" << sum;} void TestNonVirtual( const QVector <CBase *> & vec ){ QTime begT = QTime::currentTime(); int sum = 0; for (int i = 0; i < vec.size(); ++i) { CBase * base = vec[i]; for (size_t j = 0; j < NUM_CALL; ++j) { sum += base->typeNonVirtual(); // Для сравнения: оставим только вызов не виртуальной функции } } int msecs = begT.msecsTo(QTime::currentTime()); qDebug() << "TestNonVirtual time(sec): " << (msecs / 1000.0f) << "sum =" << sum;}
C++ (Qt)TestVirtual time(sec): 0.673 sum = 157286400 TestNonVirtual time(sec): 0 sum = 157286400
C++ (Qt)TestVirtual time(sec): 1.529 sum = 157286400 TestNonVirtual time(sec): 0.995 sum = 157286400
C++ (Qt)TestVirtual time(sec): 1.696 sum = 157286400 TestNonVirtual time(sec): 5.348 sum = 157286400
C++ (Qt)TestVirtual time(sec): 1.696TestNonVirtual time(sec): 1.736