dynamic_cast powinien załatwić sprawę
TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);
Plik dynamic_cast
Kluczowe rzuca punkt odniesienia z jednego wskaźnika lub odniesienia do innego typu, przeprowadza kontrolę wykonania w celu zapewnienia ważności obsady.
Jeśli spróbujesz rzutować na wskaźnik do typu, który nie jest typem rzeczywistego obiektu, wynik rzutowania będzie miał wartość NULL. Jeśli spróbujesz rzutować odwołanie do typu, który nie jest typem rzeczywistego obiektu, rzutowanie zgłosi bad_cast
wyjątek.
Upewnij się, że w klasie bazowej jest co najmniej jedna funkcja wirtualna, aby funkcja dynamic_cast działała.
Temat Wikipedii Informacje o typie czasu wykonywania
RTTI jest dostępne tylko dla klas, które są polimorficzne, co oznacza, że mają co najmniej jedną metodę wirtualną. W praktyce nie stanowi to ograniczenia, ponieważ klasy bazowe muszą mieć wirtualny destruktor, aby umożliwić obiektom klas pochodnych prawidłowe czyszczenie, jeśli zostaną usunięte ze wskaźnika podstawowego.
dynamic_cast
rzuca się, jeśli nie jest wymienny? Czy można to zrobić bez generowania rzutu?A* aptr = dynamic_cast<A*>(ptr);
// Czy nie powinno tak byćuint8_t*
? To znaczy, czy mogę to sprawdzićuint32_t* x = dynamic_cast<uint32_t*>(p)
, gdziep
jestuint8_t*
? (Próbuję znaleźć test na wykroczenia).Rzutowanie dynamiczne jest najlepsze dla twojego opisu problemu, ale chcę tylko dodać, że możesz znaleźć typ klasy za pomocą:
źródło
11MyClass
. Aby odblokować, możesz użyć biblioteki rozszerzeń ABI w programiecxxabi.h
. To daje ciabi::__cxa_demangle
prawdziwe imięNazywa się to RTTI , ale prawie na pewno chcesz ponownie rozważyć swój projekt tutaj, ponieważ znalezienie typu i robienie specjalnych rzeczy na jego podstawie sprawia, że twój kod jest bardziej kruchy.
źródło
Aby być kompletnym, zbuduję kompilację z Robocide i wskażę, że
typeid
można jej używać samodzielnie bez używania name ():Wynik:
źródło
Prawdopodobnie umieść w swoich obiektach "znacznik" ID i używaj go do rozróżniania obiektów klasy A i obiektów klasy B.
To jednak pokazuje wadę w projekcie. Idealnie byłoby, gdyby te metody w B, których A nie ma, powinny być częścią A, ale pozostawione puste, a B je nadpisuje. Eliminuje to kod specyficzny dla klasy i jest bardziej w duchu OOP.
źródło
Szukasz
dynamic_cast<B*>(pointer)
źródło
Ponieważ twoja klasa nie jest polimorficzna. Próbować:
Teraz
BaseClas
jest polimorficzny. Zmieniłem klasę na struct, ponieważ członkowie struktury są domyślnie publiczne.źródło
Twój opis jest trochę zagmatwany.
Ogólnie rzecz biorąc, chociaż niektóre implementacje C ++ mają do tego mechanizmy, nie powinieneś pytać o typ. Zamiast tego powinieneś wykonać dynamic_cast na wskaźniku do A. To spowoduje, że w czasie wykonywania zostanie sprawdzona rzeczywista zawartość wskaźnika do A. Jeśli masz B, otrzymasz wskaźnik do B. W przeciwnym razie otrzymasz wyjątek lub wartość null.
źródło
Jak wskazali inni, możesz użyć dynamic_cast. Ale generalnie użycie dynamic_cast do znalezienia typu klasy pochodnej, nad którą pracujemy, wskazuje na zły projekt. Jeśli nadpisujesz funkcję, która przyjmuje wskaźnik A jako parametr, powinna być w stanie pracować z metodami / danymi samej klasy A i nie powinna zależeć od danych klasy B. W twoim przypadku zamiast nadpisywania, jeśli jesteś pewien, że metoda, którą piszesz będzie działała tylko z klasą B, wtedy powinieneś napisać nową metodę w klasie B.
źródło
Użyj przeciążonych funkcji. Nie wymaga obsługi dynamic_cast ani nawet RTTI:
źródło
Jeśli masz dostęp do biblioteki boost, być może funkcja type_id_with_cvr () jest tym, czego potrzebujesz, która może zapewnić typ danych bez usuwania modyfikatorów const, volatile oraz && . Oto prosty przykład w C ++ 11:
Mam nadzieję, że to jest przydatne.
źródło