проблема в книжном примере или нет?
От: varnie  
Дата: 27.12.07 21:23
Оценка:
добрый день.
проясните плиз ситуацию.

у Брюса Эккеля в первом томе его "Thinking in C++" нашел интересную заметку:

A dynamic_cast requires a little bit of extra overhead to run; not much, but if you’re doing a lot of dynamic_casting (in which case you should be seriously questioning your program design) this may become a performance issue. In some cases you may know something special during downcasting that allows you to say for sure what type you’re dealing with, in which case the extra overhead of the dynamic_cast becomes unnecessary, and you can use a static_cast instead.


т.е. при down-casting можно заменить использование dynamic_cast на typeinfo + static_cast, и тем самым снизить "extra overhead".

хорошо, но почему тогда нижсеследующий пример даёт разные результаты:
#include <iostream>
#include <typeinfo>
using namespace std;

class Shape { public: virtual ~Shape() {}; };
class Circle : public Shape {};
class Square : public Shape {};

void testFirst()
{
    Circle c;
      Shape* s = &c; // Upcast: normal and OK

    Circle* cp = 0;
     Square* sp = 0;

    // Static Navigation of class hierarchies
      // requires extra type information:
      if(typeid(s) == typeid(cp)) // C++ RTTI
            cp = static_cast<Circle*>(s);
      if(typeid(s) == typeid(sp))
            sp = static_cast<Square*>(s);

    cout << "testFirst:" << endl;
      if(cp != 0)
            cout << "It's a circle !" << endl;
      if(sp != 0)
            cout << "It's a square !" << endl;
    cout << endl;
}

void testSecond()
{
    Circle c;
      Shape* s = &c; // Upcast: normal and OK

    Circle* cp = 0;
      Square* sp = 0;

    cout << "testSecond:" << endl;
    cp = dynamic_cast<Circle*>(s);
    sp = dynamic_cast<Square*>(s);

    if(cp != 0)
            cout << "It's a circle !" << endl;
      if(sp != 0)
            cout << "It's a square !" << endl;
    cout << endl;
}

int main()
{
    testFirst();
    testSecond();
        
        return 0;
} ///:~

вывод:

testFirst:

testSecond:
It's a circle !

компилил gcc.

код ф-ции void testFirst() я взял целиком и полностью с вышеупомянутой книги.
код ф-ции void testSecond() -- уже мой.

сейчас поразмыслил, и пришел к выводу, что код из книги неверный ( код ф-ции void testFirst() ), и правильный вариант должен быть следующим:
void testFirst()
{
    Circle c;
      Shape* s = &c; // Upcast: normal and OK

    Circle* cp = 0;
     Square* sp = 0;

    // Static Navigation of class hierarchies
      // requires extra type information:
      if(typeid(*s) == typeid(Circle))                 // C++ RTTI
            cp = static_cast<Circle*>(s);
      if(typeid(*s) == typeid(Square))
            sp = static_cast<Square*>(s);

    cout << "testFirst:" << endl;
      if(cp != 0)
            cout << "It's a circle !" << endl;
      if(sp != 0)
            cout << "It's a square !" << endl;
    cout << endl;
}

в этом случае обе ф-ции выдают:

It's a circle !

что будет верно.

все верно в моих выводах и корректировках исходного кода из книжки или я заблуждаюсь?
спасибо большое за прояснение.
"Я женился на первой же женщине, которая обратилась ко мне по мейлу." © Л. Торвальдс
Re: проблема в книжном примере или нет?
От: Bell Россия  
Дата: 28.12.07 07:46
Оценка: 28 (1)
Здравствуйте, varnie, Вы писали:

...

V>т.е. при down-casting можно заменить использование dynamic_cast на typeinfo + static_cast, и тем самым снизить "extra overhead".

Кое-что можно посмотреть здесь
Автор: Aera
Дата: 04.08.03


...

V>сейчас поразмыслил, и пришел к выводу, что код из книги неверный ( код ф-ции void testFirst() ), и правильный вариант должен быть следующим:


...

V>все верно в моих выводах и корректировках исходного кода из книжки или я заблуждаюсь?

Да, твои выводы верны. Этот же самый вопрос уже задавался здесь
Автор: alexxxander
Дата: 12.07.04
.
Строки
if(typeid(s) == typeid(cp))
if(typeid(s) == typeid(sp))

нигогда не дадут true. Для получения информации о динамическом типе, аргументом typeid должно быть l-value полиморфного типа (5.2.8/2)
Любите книгу — источник знаний (с) М.Горький
Re[2]: проблема в книжном примере или нет?
От: Lorenzo_LAMAS  
Дата: 28.12.07 10:48
Оценка:
Здравствуйте, Bell, Вы писали:

И вновь я хотел метнуться писать ответ! Хорошо, все же прочитал твой сначала. Глядишь, научимся избегать избыточности
Of course, the code must be complete enough to compile and link.
Re[3]: проблема в книжном примере или нет?
От: Bell Россия  
Дата: 28.12.07 10:53
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>И вновь я хотел метнуться писать ответ! Хорошо, все же прочитал твой сначала. Глядишь, научимся избегать избыточности


А если все начнут пользоваться поиском ....

... но тогда будет совсем скучно
Любите книгу — источник знаний (с) М.Горький
Re[2]: проблема в книжном примере или нет?
От: varnie  
Дата: 28.12.07 15:28
Оценка:
Здравствуйте, Bell!

спасибо за развернутый ответ. я рад что все у меня теперь встало на свои места с этой непоняткой!!

про поиск я принял на заметку.
"Я женился на первой же женщине, которая обратилась ко мне по мейлу." © Л. Торвальдс
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.