cours cast - C++ - Programmation
Marsh Posté le 28-08-2003 à 13:38:10
j'en ai pas. en tout cas, ne jamais utiliser (type), mais plutot type() (constructeur)
ensuite le static_cast (mot clef) c'est pour les cast bien définis et sur (comme par exemple, Derivée * vers Base *)
le reinterpret_cast, c'est le plus bourrin, l'équivalent du (type) en C, qui revient à dire au compilateur "ferme ta gueule", on verra plus tard si ça plante, ça sera tant pis pour moi
Marsh Posté le 28-08-2003 à 13:52:25
En général :
- static_cast<>
Plutot pour float => int, int => char, ou autres scalaires. Ca marche aussi pour les pointeurs mais perso je prefere reinterpret_cast (qui est un peu moins safe).
- reinterpret_cast<>
Pour scalaire => pointeur et pointeur => scalaire, ou entre pointeurs (ca balance plein de warnings en compilant avec les warnings 64-bit par contre).
- const_cast<>
Rarement utile, a part pour certains messages Win32 ou il faut donner un LPTSTR dans une structure à partir d'un basic_string, et qu'on sait que ça ne sera pas modifié.
- dynamic_cast<>
Faut avoir rtti activé pour que ca fonctionne, et en général si on en a besoin c'est que le design du programme est pas terrible.
- cast C
Inutile en C++.
- type( ... )
C'est pas un cast, c'est un constructeur.
Marsh Posté le 28-08-2003 à 13:54:25
Citation : - dynamic_cast<> |
je dirai tout le contraire. ça existe des compilos ou il faut bidouiller pour avoir de RTTI? ça t'arrive jamais de devoir convertir un Base* en Truc*
Marsh Posté le 28-08-2003 à 14:02:02
d'accord, j'ai pas tout compris mais j'y réfléchis
c quoi rtti ?
Marsh Posté le 28-08-2003 à 14:10:21
BlackGoddess a écrit : d'accord, j'ai pas tout compris mais j'y réfléchis |
Run Time Type Informations
fais un #include <tupeinfo>
et amuse toi avec
cout << typeid(variable).name() << endl;
ou
typeid(machin)==typeid(truc)
pour commencer
Marsh Posté le 28-08-2003 à 14:11:38
BlackGoddess a écrit : d'accord, j'ai pas tout compris mais j'y réfléchis |
Run Time Type Informations me semble
Marsh Posté le 28-08-2003 à 15:04:29
Taz a écrit :
je dirai tout le contraire. ça existe des compilos ou il faut bidouiller pour avoir de RTTI? ça t'arrive jamais de devoir convertir un Base* en Truc* |
Non ca m'arrive jamais de devoir convertir une Base * en un Truc *. Et si même ca arrivait (ce qui n'est jamais arrivé en 7 ans), ce serait fait autrement qu'avec RTTI, vu que c'est un peu énorme pour une seule utilisation. Et dans Visual C++ il faut l'activer (le RTTI).
Marsh Posté le 28-08-2003 à 15:40:55
Ashe2 a écrit : - cast C |
J'étais prêt à répondre que ce n'était pas vrai en me basant sur cet article, mais je me suis dis que j'allais tester auparavant.
Code :
|
Et surprise, Visual Studio 6.0 SP5 et gcc 2.95.3 ne donnent pas le même résultat et aucun ne semble se comporter comme précisé dans l'article ci-dessus.
Visual Studio 6.0 SP5 :
gcc 2.95.3 :
Quel comportement est le bon ?
Selon moi, le static_cast devrait générer une erreur. En effet, la conversion de Derived en Base n'est pas "normale" (car Base est caché par l'héritage privé). Le reinterpret_cast peut aussi fonctionner (je trouverais cela assez logique) mais selon l'article ci-dessus, il ne devrait pas. Le cast C doit fonctionner sans même un warning (je fais tout ce que je veux).
Il faudrait tester avec d'autres compilateurs également.
-- Edit --
quelques modifications pour rendre le tout plus clair
Marsh Posté le 28-08-2003 à 16:07:50
Taz a écrit : gcc2.95 est vieux |
Tout comme Visual Studio 6.0 SP5.
Désolé, mais j'ai utilisé les compilateurs que j'avais sous la main. A voir donc avec des compilateurs plus récents.
Taz a écrit : et moi je compile en |
Je n'utilise jamais gcc. J'ai regardé un tutorial rapidement et j'ai compilé avec "-g -Wall test.cpp -o test". Cependant en recompilant avec tes options cela ne change pas grand chose. Il indique juste que j'utilise un cast "old-style", ce qui n'est pas ce que je cherche à savoir.
Mais bon, ce qui m'intéresse surtout c'est de savoir quel est le comportement standard. Car entre l'article et les deux compilateurs que j'ai pu essayé, personne ne me donne la même réponse.
Marsh Posté le 27-04-2004 à 11:05:12
up (bon gros deterage la meme)
je me renseigne sur les cast en C++, et je suis tombe sur ce topic
mais j'ai pas trop saisit le const_cast et encore moins le dynamic_cast
qqn aurait des exemples plus precis ?
a+
Marsh Posté le 27-04-2004 à 11:35:08
Ashe2 a écrit : |
et tu crois vraiment que les gars qui ont pensé à cet opérateur de cast se sont dits "tient, on va mettre aussi celui-là pour ceux qui concoivent comme des gorets" ?
tu ne connais peux être pas de cas où une telle utilisation est nécessaire, mais il y en a.
Marsh Posté le 27-04-2004 à 11:41:49
myst78 >> j'ai essayé de faire un tutorial sur le static_cast / dynamic_cast :
http://forums.dev-communaute.com/i [...] f=11&t=214
Marsh Posté le 27-04-2004 à 13:03:17
blackgoddess a écrit : myst78 >> j'ai essayé de faire un tutorial sur le static_cast / dynamic_cast : |
hum, si j'ai bien compris ton tut, le dynamic c'est pour descendre dans la hierarchie et le static pour remonter ?
mais ca marche pas dans l'autre sens ?
genre dans ton tut si ej fais
Code :
|
ca passe ou pas ? si oui, quel est la difference, et pourquoi choisir le dynamic plutot que le static ?
Marsh Posté le 27-04-2004 à 13:05:57
ça passe à la compilation, mais tu ne connaitras le résultat du cast qu'à l'execution. Si celui-ci échoue, alors ton pointeur vaut 0, sinon il vaut ListeAnimaux[i] (mais avec le type Chien *).
Marsh Posté le 27-04-2004 à 13:09:37
ben euh oui d'accord, alors pardon d'insister et de jouer les neuneus la mais je pige toujours pas la difference
tu parles duquel la en plus ?
Marsh Posté le 27-04-2004 à 13:09:42
c'est quoi comme type ListAnimaux[i] ? si c'est pas apparenté à un chien, ça ne passera pas à la compilation : il faut alors utilisé le dynamic_cast qui peut échouer. sinon, si c'est un sous-type de chien, pas besoin de cast
Marsh Posté le 27-04-2004 à 13:10:51
Taz a écrit : c'est quoi comme type ListAnimaux[i] ? si c'est pas apparenté à un chien, ça ne passera pas à la compilation : il faut alors utilisé le dynamic_cast qui peut échouer. sinon, si c'est un sous-type de chien, pas besoin de cast |
Code :
|
Marsh Posté le 27-04-2004 à 13:12:01
bah si Chien est un Animal, il faut utiliser le dynamic_cast
Marsh Posté le 27-04-2004 à 13:13:29
note:
dans static_cast, il y a static
dans dynamic_cast, il y a dynamic
autrement dit:
il y en a un dont tu connais le résultat à la compilation
tu ne peux connaitre le résultat de l'autre 'à l'execution
Marsh Posté le 27-04-2004 à 13:14:49
*insiste encore *
d'accord mais pourquoi dynamic plutot que static alors ? Dans quel cas on choisit l'un plutot que l'autre
Marsh Posté le 27-04-2004 à 13:15:28
tu peux dire avec certitude si ton Animal* pointe en fait vers un Chien ?
Marsh Posté le 27-04-2004 à 13:16:23
Taz a écrit : tu peux dire avec certitude si ton Animal* pointe en fait vers un Chien ? |
non
Marsh Posté le 27-04-2004 à 13:17:42
ok je crois que j'ai compris
merci de votre patience
Marsh Posté le 27-04-2004 à 14:42:26
Chien et Chat héritent d'Animal. Ceci est défini pour la compilation, le compilo le sait donc. Le static_cast, qui permet d'aller d'un type Chat ou Chien vers un type Animal, (en effet, si un objet Chien ou Chat hérite des méthodes d'un objet Animal) et donc validé à la compilation. Par contre, l'inverse n'est pas forcément vrai : un objet de type Animal pourra en réalité être une instance de Chien, de Chat ou d'animal. Le test ne peut pas être effectué par le compilateur, et c'est donc à l'exécution qu'il est validé, d'où le nom : dynamic_cast.
Marsh Posté le 27-04-2004 à 14:43:51
"qui permet d'aller d'un type Chat ou Chien vers un type Animal" pas besoin de static_cast, Chat est un Animal.
Marsh Posté le 27-04-2004 à 14:50:56
oui, on peut écrire directement
Animal *a = new Chien();
a la place de
Animal *a = static_cast<Animal*>(new Chien());
mais j'ai préféré la 2eme pour bien mettre en evidence le transtypage qui doit être implict dans le 2eme non ?
quand un static_cast est-il vraiment nécéssaire ?
sinon, j'ai entendu dire que les opérateurs de transtypage C++ pouvaient être appelés avec des références au lieu des pointeurs, dans quelles conditions c'est possible ?
Marsh Posté le 27-04-2004 à 14:55:35
mais y a pas de transtypage : un Chien est un animal
tu t'amuse pas à écrire
int i= static_cast<int>(42) quand même ?
le static_cast est nécessaire quand tu dois faire une __conversion__ bien défini à la compilation. encore faut il que tu es une conversion à faire
Marsh Posté le 27-04-2004 à 14:55:38
merci pour les precisions, j'avais bien fini par comprendre ca
sinon je me pose aussi tes 2 questions (surtout la premiere du coup)...
Marsh Posté le 27-04-2004 à 15:15:05
Taz > pourrait-on avoir un petit exemple ou la conversion est nécéssaire stp ?
Marsh Posté le 27-04-2004 à 15:22:42
le static_cast j'ai du mal à l'utiliser pour caster le signe (convertir un size_t en int ou vice versa).
Je l'emploie plutot pour les type (int <-> float) ou la taille (short <-> int).
Marsh Posté le 27-04-2004 à 15:29:59
ben l'exemple devenu célèbre
Code :
|
// & ou *
en fait le static_cast ne sert pas tant à convertir, puisque le C++ est laxiste, beaucoup de choses passent implicitement, mais souvent à expliciter le type
Marsh Posté le 27-04-2004 à 15:32:03
Citation : const char *s = "tokra"; |
Alors, toujours pas trouvé d'utilité aux char * ?
Marsh Posté le 13-05-2004 à 12:55:40
Code :
|
Marsh Posté le 28-08-2003 à 13:28:34
bonjour,
je n'ai pas tres bien saisie dans quels cas utiliser un cast plutot qu'un autre comme static_cast<type>var plutot que reinterpret_cast<type>var.
pour l'instant j'utilise (type)var.
qq1 pourrait m'expliquer ou me donner un lien ?
---------------
-( BlackGoddess )-