2013-05-04 18 views
5

Perché questo codice non funziona?Impossibile eseguire il cast dinamico quando si utilizza dynamic_pointer_cast

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

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

ottengo il seguente errore:

/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 eredita da Event quindi credo che il problema è che non riesco a lanciare in questa direzione. Ma ep->pop() potrebbe restituire un oggetto di tipo Event o TrackerEvent. E speravo che quando provo a lanciarlo a TrackerEvent e ritorna NULL Vorrei sapere se ho un Event o TrackerEvent ...

Come potrei farlo?

+3

È necessario avere almeno un metodo virtuale per utilizzare dynmaic_cast. – stardust

risposta

10

Il compilatore ti dice cosa sta succedendo alla fine del messaggio:

(source type is not polymorphic)

tua classe base Event deve avere almeno un virtual funzione membro (vale a dire essere un tipo polimorfico) in per consentire lanci dinamici. Si potrebbe fare il distruttore di Event virtuale:

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

Ecco una live example with polymorphic types, mostrando che le compila codice (rimuovendo il distruttore virtuale potrebbe causare un errore di compilazione similar to the one you are seeing).

Come detto correttamente Luc Danton nei commenti, una versione in default di un distruttore virtuale può essere definito in questo modo (se il compilatore è C++ 11-compliant in questo senso):

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

@LucDanton: Giusto, ho dimenticato di dirlo. Modificato, grazie –

3

Per eseguire un dynamic_cast, il tipo da cui si sta trasmettendo deve essere polimorfico. Perché questo sia vero, deve avere o ereditare alcuni membri virtuali. Assicurati che l'Event abbia una funzione membro virtuale (per lo meno un distruttore virtuale).