Outils pour utilisateurs

Outils du site


lang:cpp:cast

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
lang:cpp:cast [2020/03/04 07:55] – Ajout de "Cast vers un parent d'un héritage multiple" rootlang:cpp:cast [2025/07/28 13:07] (Version actuelle) – [dynamic_cast] : précision sur la vitesse des dynamic_cast root
Ligne 37: Ligne 37:
  
 ''dynamic_cast'' permet de vérifier que le ''static_cast'' est possible. Il est nécessaire que la classe soit polymorphique (au moins une méthode virtuelle). ''dynamic_cast'' permet de vérifier que le ''static_cast'' est possible. Il est nécessaire que la classe soit polymorphique (au moins une méthode virtuelle).
 +
 +Le ''dynamic_cast'' utilise le pointeur de la table virtuel de l'objet et analyse une table contenant tous les pointeurs de tables virtuels. Si le programme est très gros et contient beaucoup de classes polymorphiques, le ''dynamic_cast'' peut être lent s'il est appelé très fréquemment. C'est pour cette raison que certains programmes implémentent une méthode virtuelle ''get_type'' qui renvoie un ''enum'' pour vérifier si le cast est possible.
 +
 +[[https://thewayofc.blogspot.com/2007/09/alternative-ways-to-implement-downcasts.html| Alternative ways to implement downcasts]] {{ :lang:cpp:cast:the_way_of_c_c_alternative_ways_to_implement_downcasts_7_28_2025_1_06_49_pm_.html |Archive du 11/09/2007 le 28/07/2025}}
  
 <code cpp> <code cpp>
Ligne 63: Ligne 67:
 </code> </code>
  
 +Il est aussi possible d'utiliser ''dynamic_cast'' avec des références. En cas d'échec, une exception ''std::bad_cast'' sera généré.
 +
 +<code c++>
 +#include <typeinfo>
 +
 +class A {
 + public:
 +  virtual ~A() = default;
 +};
 +
 +class B : public A {};
 +
 +class C {};
 +
 +int main() {
 +  B b;
 +  A& a = dynamic_cast<A&>(b);
 +  try {
 +    C& c = dynamic_cast<C&>(b);
 +  } catch (const std::bad_cast&) {
 +    return 1;
 +  }
 +  return 0;
 +}
 +</code>
 +
 +[[https://www.ibm.com/docs/en/i/7.2?topic=operator-dynamic-casts-references|Dynamic Casts with References]] {{ :lang:cpp:cast:dynamic_casts_with_references_-_ibm_documentation_23_06_2023_16_43_55_.html |Archive du 14/04/2021 le 23/06/2023}}
 ===const_cast=== ===const_cast===
  
Ligne 96: Ligne 127:
  
 ===Cast vers un parent d'un héritage multiple=== ===Cast vers un parent d'un héritage multiple===
-{{ lang:cpp:heritage:heritage_multiple.svg?300 |}}+{{ lang:cpp:heritage:heritage_multiple.svg |}}
  
 Depuis ''Parent1'', caster ''this'' vers ''Parent2''. Depuis ''Parent1'', caster ''this'' vers ''Parent2''.
Ligne 109: Ligne 140:
 Parent2* p = static_cast<Enfant*>(this); Parent2* p = static_cast<Enfant*>(this);
 </code> </code>
 +
 +===reinterpret_cast sur une classe avec héritage===
 +Un ''static_cast'' ou un ''dynamic_cast'' ne pose pas de problème dans le cas d'héritage multiple.
 +
 +Par contre, un ''reinterpret_cast'' d'un ''void *'' doit toujours se faire sur la classe la plus basse (la plus enfant). Un ''void *'' ne possède aucune information du type de la classe et donc le compilateur ne sait pas comment s'en sortir. Par exemple avec les méthodes virtuelles, il ne peut pas savoir à quelle classe appartient la première méthode en tête de la ''vtable''. Il y a les mêmes problèmes avec les attributs de la classe.
 +
 +[[https://stackoverflow.com/questions/2379427/multiple-inheritance-unexpected-result-after-cast-from-void-to-2nd-base-class|multiple inheritance: unexpected result after cast from void * to 2nd base class]] {{ :lang:cpp:heritage:c_-_multiple_inheritance_unexpected_result_after_cast_from_void_to_2nd_base_class_-_stack_overflow_2019-12-19_2_21_51_pm_.html |Archive du 04/03/2010 le 19/12/2019}}
  
 ===Les détecters avec sanitizer=== ===Les détecters avec sanitizer===
Ligne 137: Ligne 175:
 Les classes A et B étant identiques, il est normal que le programme s'exécute correctement. Les classes A et B étant identiques, il est normal que le programme s'exécute correctement.
  
-Mais avec un sanitizer ''clang++ -fsanitize=undefined main.cc -o a.out -flto -fvisibility=hidden'' :+Mais avec un sanitizer ''clang++ -fsanitize=undefined -fno-sanitize-recover=all main.cc -o a.out -flto -fvisibility=hidden'' :
  
   main.cc:17:13: runtime error: member call on address 0x7ffc03ba2878 which does not point to an object of type 'B'   main.cc:17:13: runtime error: member call on address 0x7ffc03ba2878 which does not point to an object of type 'B'
lang/cpp/cast.1583304933.txt.gz · Dernière modification : de root