2013-08-09 41 views
7

Nie mogę poprawnie uzyskać funkcji typeid. Am I czegoś brakujeTypid nie działa poprawnie

Kod:

class A 
{ 
    public: 
    int a1; 
    A() 
    { 
    } 
}; 


class B: public A 
{ 
    public: 
    int b1; 
    B() 
    { 
    } 
}; 


int main() 
{ 
    B tempb; 
    A tempa; 
    A * ptempa; 
    ptempa = &tempb; 

    std::cout << typeid(tempb).name() << std::endl; 
    std::cout << typeid(tempa).name() << std::endl; 
    std::cout << typeid(*ptempa).name() << std::endl; 

    return 0; 
} 

Zawsze drukuje:

klasy B klasy A klasy A

Używam VS2010 dla mojego projektu

+0

Zachowuje się tak samo, używając Clang 4.2. Zgadzam się, że wygląda źle.Z definicji dokumentacji typid podaje typ wskazanego wskaźnika, a nie typ wskaźnika. Przepraszam, że to nie pomoże. Wsparcie moralne ... –

Odpowiedz

9

Obiekt, na który wskazuje, musi być polimorficzny, aby działał zgodnie z oczekiwaniami. Jeśli metody A miałyby virtual, to Twój kod działałby zgodnie z oczekiwaniami, na przykład dodając wirtualny destruktor, który I demo live here using gcc.

żądanie forma sekcji 5.2.8 IDENTYFIKACJA TYP C++ draft standard punkt mówi:

Gdy typeid nakłada się glvalue ekspresji którego typ jest polimorficzne typu klasy (10.3), w wyniku dotyczy obiekt std :: type_info reprezentujący typ najbardziej wyprowadzonego obiektu (1.8) [...]

Który dotyczy w przypadku, gdy mamy metodę virtual, w przypadku, gdy nie masz rodzaj polimorficzny tak ustęp Dotyczy:

Kiedy typeid jest stosowana do wyrażenia innego niż glvalue z polimorficznych typu klasy wynik odnosi się do std :: type_info obiektu reprezentującego statyczny typ ekspresji

Więc dostaniesz z powrotem static typu, który jest A.

Wystarczy być trochę bardziej kompletna sekcja 10.3wirtualne funkcje mówi:

wirtualne funkcje wsparcia programowania dynamicznego wiązania i obiektowego . Klasą, która deklaruje lub dziedziczy funkcję wirtualną, jest nazywana klasą polimorficzną.

20

Problem polega na tym, że A nie ma funkcji wirtualnych, więc nie jest traktowany jako polimorficzny rodzaj. W rezultacie, typeid wyszukuje zadeklarowany typ wskaźnika, a nie rzeczywisty typ obiektu, który wskazuje.

+0

Ahham. Dobrze wiedzieć! (I miałeś rację, 'dynamic_cast <>' nawet nie kompiluje.) –

+0

Przynajmniej każda klasa, która ma zostać odziedziczona, powinna mieć wirtualny dtor, więc nazwałbym niepoprawny projekt OP. – KitsuneYMG

+0

@KitsuneYMG - 'std :: iterator' jest zaprojektowany do wyprowadzenia z wirtualnego destruktora i nie ma takiego wirtualnego destruktora.Tak właśnie powinno być: –

0

Myśląc o tym podczas koszenia trawnika ... Wskaźnik nie może wiedzieć, na jaki rodzaj obiektu wskazuje. Informacja o typie jest przechowywana ze wskaźnikiem i nie zmienia się tego przez wskazywanie na klasę pochodną (B). Więc potrzebujesz typecast, aby zmienić typ wskaźnika, a wyjście IS zgodnie z oczekiwaniami.

Powiązane problemy