2011-12-12 11 views
32

Czy można dziedziczyć bez metod wirtualnych? Kompilator mówi, że poniższy kod nie jest polimorficzny.Nie można obniżyć, ponieważ klasa nie jest polimorficzna?

Przykład:

Class A(){ 
    int a; 
    int getA(){return a;}; 
} 


Class B(): A(){ 
    int b; 
    int getB(){return b;}; 
} 

W innej klasie staramy się przygnębiony z obiektu A do B obiektu:

A *a; 
B *b = dynamic_cast<B*>(a) 

ale to daje następujący błąd:

cannot dynamic_cast ... (source type is polymorphic) 
+1

'a' nie jest wskaźnikiem. Czy tak to jest w twoim kodzie? – littleadv

+0

Przepraszam, a jest w rzeczywistości wskaźnikiem. – wbarksdale

+0

A czy czas kompilacji błędów lub czas wykonywania? Jeśli działa, to IMHO jest oczekiwanym zachowaniem. – littleadv

Odpowiedz

56

Niepoprawne błędy składni, nie można uzyskać dynamic_cast typ nie-polimorficzny. static_cast to rzutowanie, którego używałbyś w tym przypadku, jeśli wiesz, że jest to faktycznie obiekt typu celu.

Powód: static_cast w zasadzie kompilator wykonuje test w czasie kompilacji "Czy dane wejściowe mogą być rzutowane na wyjście?" To może być używane w przypadkach, w których rzutujesz w dół lub w dół hierarchię wskaźników (lub odniesień). Ale sprawdzanie odbywa się tylko podczas kompilacji, a kompilator zakłada, że ​​wiesz, co robisz.

dynamic_cast może być używany tylko w przypadku wskaźnika lub odnośnika, a oprócz sprawdzenia czasu kompilacji wykonuje dodatkowe sprawdzenie, czy rzut jest legalny. Wymaga to, aby dana klasa posiadała co najmniej jedną wirtualną metodę, która pozwala kompilatorowi (jeśli obsługuje on RTTI) na przeprowadzenie dodatkowej kontroli. Jeśli jednak dany typ nie ma żadnych metod wirtualnych, nie można go użyć.

Najprostszym przypadkiem, a prawdopodobnie warto, jeśli podajesz wskaźniki podobne do tego, jest rozważenie uczynienia destruktora klasy podstawowej wirtualnym. Oprócz umożliwienia używania rzutowania dynamicznego pozwala również wywoływać odpowiednie destruktory po usunięciu wskaźnika klasy bazowej.

+0

Wielkie dzięki za wiedzę. To się udało. – wbarksdale

2
A a; 
B *b = dynamic_cast<B*>(a) 

Tutaj a jest obiektem, a b jest wskaźnikiem.

W rzeczywistości, upcasting i downcasting są dozwolone w C++. Ale przy korzystaniu z downcastingu należy zwrócić uwagę na dwie rzeczy: 1 Nadklasa powinna mieć co najmniej jedną metodę wirtualną. 2 Ponieważ nadklasa jest "mniejsza" niż podklasa, należy ostrożnie używać obiektu pamięci.

4

Tak, dynamic_cast dla typów nie-polimorficznych jest niedozwolona. Klasa podstawowa musi mieć co najmniej jedną metodę wirtualną. Dopiero wtedy tę klasę można nazwać polimorficzną.

Ten artykuł wyjaśnia podobny przykład: http://www.cplusplus.com/doc/tutorial/typecasting/

+0

Dave dał fajną odpowiedź. Nie mam uprawnień do komentowania jego postu. Tak, komentuję tutaj. –

18

Trzeba przynajmniej jedną metodę wirtualną w klasie dla run-time type information (RTTI) z powodzeniem stosować operatora dynamic_cast.

11

po prostu ustaw wirtualny destruktor (zawsze dla każdej klasy tylko dla bezpieczeństwa).

+7

nie dla żadnej klasy, ale dla klasy, która ma być klasą podstawową – ParokshaX

Powiązane problemy