OVH Cloud OVH Cloud

dynamic_cast Vs typeid & static_cast

5 réponses
Avatar
Aurélien REGAT-BARREL
Bonjour à tous,
Quelle différence / avantage y-a-t-il à utiliser dynamic_cast par rapport au
couple typeid + static_cast :

class A
{
virtual void t() {}
};

class B : public A {};

class C : public A {};

B * cast_to_B( A * a )
{
try
{
return dynamic_cast<B*>( a );
}
catch ( std::bad_cast & )
{
return 0;
}
}

C * cast_to_C( A * a )
{
if ( typeid(*a) == typeid(C) )
{
return static_cast<C*>( a );
}
return 0;
}

A vu de nez je dirais la performance. J'ai aussi noté que ne pas mettre de
fonction virtuelle dans A empêche de compiler cast_to_B et fait échouer au
runtime cast_to_C.
Y-a-t-il autre chose ?
Merci pour votre participation.

--
Aurélien REGAT-BARREL

5 réponses

Avatar
Loïc Joly
Aurélien REGAT-BARREL wrote:
Bonjour à tous,
Quelle différence / avantage y-a-t-il à utiliser dynamic_cast par rapport au
couple typeid + static_cast :

class A
{
virtual void t() {}
};

class B : public A {};

class C : public A {};

B * cast_to_B( A * a )
{
try
{
return dynamic_cast<B*>( a );
}
catch ( std::bad_cast & )
{
return 0;
}
}


Remarque : Quand on dynamic_cast des pointeurs, dynamic_cast retourne
en cas d'échec. C'est quand on dynamic_cast des références qu'il lance
une exception.



C * cast_to_C( A * a )
{
if ( typeid(*a) == typeid(C) )
{
return static_cast<C*>( a );
}
return 0;
}



class BB : public B {};
class CC : public C {};

int main()
{
A* ab = new BB;
A* ac = new CC;
B* b = cast_to_b(ab); // Marche
C* c = cast_to_c(ac); // Ne marche pas
}

--
Loïc

Avatar
Aurélien REGAT-BARREL
Remarque : Quand on dynamic_cast des pointeurs, dynamic_cast retourne
en cas d'échec. C'est quand on dynamic_cast des références qu'il lance
une exception.


Ah oui, je ne le savais pas.

class BB : public B {};
class CC : public C {};

int main()
{
A* ab = new BB;
A* ac = new CC;
B* b = cast_to_b(ab); // Marche
C* c = cast_to_c(ac); // Ne marche pas
}


CQFD.
Merci.

--
Aurélien REGAT-BARREL

Avatar
kanze
"Aurélien REGAT-BARREL" wrote in
message news:<4133288f$0$22038$...

Quelle différence / avantage y-a-t-il à utiliser dynamic_cast par
rapport au couple typeid + static_cast :


Ils ne font pas la même chose. Le dynamic_cast fonctionne quelque soit
le type dynamique de l'objet, à condition que la classe en question en
fait partie de la hièrarchie d'héritage. Les typeid ne compare égaux que
si les types dynamiques (les plus dérivés) sont identique.

Dans la pratique, je ne crois pas m'être jamais servi d'un typeid suivi
d'un static_cast. (Dans la pratique, je ne suis pas sûr de m'être servi
de typeid autrement que pour les fins de deboggage.)

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
Falk Tannhäuser
Aurélien REGAT-BARREL wrote:
CQFD.
Merci.


Et puis, le dynamic_cast marche même entre des classes n'ayant
pas de relation directe d'héritage ("cross cast") :
______________________________________________________________
#include <typeinfo>
#include <iostream>
#include <ostream>

struct A { virtual ~A() {} };
struct B { void hello() const { std::cout << "Hello world!" << std::endl; } };
void foo(A& a) { B& b = dynamic_cast<B&>(a); b.hello(); }

struct C : public A, public B {};

int main()
{
A a;
C c;
try
{
foo(c);
foo(a);
}
catch(std::bad_cast&)
{
std::cerr << "Bad cast occured!" << std::endl;
return 1;
}
return 0;
}
______________________________________________________________

Dans ce bout de code, le premier dynamic_cast réussit.

Falk

Avatar
Aurélien REGAT-BARREL
OK.
Merci.

--
Aurélien REGAT-BARREL