2013-05-04 20 views
5

Dlaczego ten kod nie działa?Nie można rzutować dynamicznie podczas używania dynamic_pointer_cast

std::shared_ptr<Event> e = ep->pop(); 
std::shared_ptr<TrackerEvent> t; 

t = std::dynamic_pointer_cast<TrackerEvent>(e); 

pojawia się następujący błąd:

/usr/include/c++/4.6/bits/shared_ptr.h:386: error: cannot dynamic_cast '(& __r)->std::shared_ptr<Event>::<anonymous>.std::__shared_ptr<_Tp, _Lp>::get [with _Tp = Event, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]()' (of type 'class Event*') to type 'class TrackerEvent*' (source type is not polymorphic) 

TrackerEvent dziedziczy z Event więc myślę, że problem jest, że nie mogę rzucić w tym kierunku. Ale ep->pop() może zwrócić obiekt typu Event lub TrackerEvent. I mam nadzieję, że kiedy próbuję oddać go do TrackerEvent i zwraca NULL mam wiedzieć czy mam Event lub TrackerEvent ...

Jak to zrobić? Aby uzyskać numer

+3

Musisz mieć co najmniej jedną wirtualną metodę używania dynmaic_cast. – stardust

Odpowiedz

10

Kompilator jest informacją, co się dzieje na końcu wiadomości:

(source type is not polymorphic)

Twój Event klasa bazowa musi mieć co najmniej jeden virtual funkcji składowej (czyli być polimorficzny typ) w aby umożliwić dynamiczne rzuty. Można zrobić destruktora Event wirtualnej:

class Event 
{ 
public: 
    virtual ~Event() { /* whatever goes here, or nothing... */ } 
    // ... 
}; 

Oto live example with polymorphic types, pokazując, że kompiluje kod (usuwanie wirtualnego destruktora spowoduje błąd kompilacji similar to the one you are seeing).

Jak słusznie wspomniał Luc Danton w komentarzach, o niespłaconych wersja wirtualnego destruktora można zdefiniować w ten sposób (jeśli kompilator C++ 11 zgodny w tym zakresie):

class Event 
{ 
public: 
    virtual ~Event() = default; 
    // ... 
}; 
+0

@LucDanton: Racja, zapomniałem o tym wspomnieć. Edytowane, dziękuję –

3

, typ, z którego chcesz przesyłać, musi być polimorficzny. Aby to było prawdą, musi mieć lub dziedziczyć niektórych wirtualnych członków. Upewnij się, że Event ma funkcję wirtualnego elementu (przynajmniej wirtualny destruktor).