Dinamikus_cast

A C ++ programozási nyelv , az üzemeltető dynamic_casttagja a futásidejű típus információ (RTTI) rendszer, amely végrehajtja típuskonverzió . A C nyelvtől örökölt szereplőgárdától eltérően azonban a típusvizsgálat futás közben történik, és vagy kivételt hoz a referenciák esetében, vagy egy null mutatót mutat a mutatók esetében, ha a típusok nem kompatibilisek. Tehát dynamic_castinkább egy típusátalakítóként viselkedik egy olyan nyelven, mint a Java , nem pedig a C nyelv értelmében vett átalakításként, amely futás közben semmit sem ellenőriz.

Minta kód

Legyen egy osztály A, örökölt B. Tegyük fel, hogy egy metódus Aargumentumként egy típusú objektumot vesz fel , amely további feldolgozást hajt végre, ha az objektum valójában típusú példány B. Ez dynamic_casta következőképpen érhető el :

#include <typeinfo> // Pour std::bad_cast #include <iostream> // Pour std::cerr, etc. class A { public: // Puisque RTTI est incluse dans la table des méthodes virtuelles (la vtable), // il devrait y avoir au moins une fonction virtuelle pure. virtual void foo() = 0; // autres membres... }; class B : public A { public: void foo() { /* ... */ } void methodSpecificToB() { /* ... */ } // autres membres... }; void my_function(A& my_a) { try { B& my_b = dynamic_cast<B&>(my_a); my_b.methodSpecificToB(); } catch (const std::bad_cast& e) { std::cerr << e.what() << std::endl; std::cerr << "Cet objet n'est pas de type B" << std::endl; } }

A megfelelő változat my_functionmegadható hivatkozások helyett mutatókkal:

void my_function(A* my_a) { B* my_b = dynamic_cast<B*>(my_a); if (my_b != nullptr) my_b->methodSpecificToB(); else std::cerr << "Cet objet n'est pas de type B" << std::endl; }

Végrehajtás

Ahhoz, hogy megértsük a működését, megnézhetjük, hogy a dynamic_cast miként valósítható meg manuálisan.

#include <iostream> // Pour std::cerr, etc. class B; class C; class A { /// la méthode qui permettra de connaitre le type complet de notre objet virtual const char get_type_for_dynamic_cast() const = 0; public: B* dynamic_cast_to_B() { if (get_type_for_dynamic_cast() != 'B') return 0; return static_cast<B*>(this); } C* dynamic_cast_to_C() { if (get_type_for_dynamic_cast() != 'C') return 0; return static_cast<C*>(this); } }; class B : public A { int data; const char get_type_for_dynamic_cast() const { return 'B'; } public: B(int data) : data(data) { } void methode() { std::cout << data << "\n"; } }; class C : public A { char* data; const char get_type_for_dynamic_cast() const { return 'C'; } public: C(char* data) : data(data) { } void methode() { std::cout << data << "\n"; } }; void ma_fonction(A* a) { if (B* b = a->dynamic_cast_to_B()) b->methode(); else if (C* c = a->dynamic_cast_to_C()) c->methode(); else { // erreur de type } }

Látjuk, hogy emlékezetünkben, ha az osztályainknak már van VTable-je , akkor a költség majdnem nulla, mivel csak hozzáadtunk egy módszert az egyes osztályok VTable-jéhez . A számítási időt tekintve a költségek meglehetősen alacsonyak maradnak: a normál mutatók száma nem igényel számítást, míg itt tiszta virtuális módszert kell meghívnunk (amelynek címét a VTable-ben kell elolvasni ), és meg kell vizsgálnunk annak visszatérési értékét.

Lásd is

Kapcsolódó cikkek

Külső linkek