2013-05-04 12 views
5

Warum funktioniert dieser Code nicht?Dynamische Umwandlung bei Verwendung von dynamic_pointer_cast nicht möglich

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

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

bekomme ich folgende Fehlermeldung:

/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 erbt von Event also denke ich, das Problem ist, dass ich nicht in diese Richtung werfen können. Aber ep->pop() kann entweder ein Objekt vom Typ Event oder TrackerEvent zurückgeben. Und ich habe gehofft, dass, wenn ich versuche, es zu TrackerEvent zu werfen und es gibt NULL würde ich wissen, ob ich ein Event oder TrackerEvent habe ...

Wie würde ich das tun?

+3

Sie müssen habe mindestens eine virtuelle Methode, um dynmaic_cast zu verwenden. – stardust

Antwort

10

Der Compiler sagt Ihnen, was am Ende der Nachricht wird auf:

(source type is not polymorphic)

Ihre Event Basisklasse muss mindestens eine virtual Member-Funktion (dh sein ein polymorph Typ) haben in um dynamische Umsetzungen zu ermöglichen. Sie konnten die destructor von Event virtuellen machen:

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

Hier ist ein live example with polymorphic types, die zeigen, dass der Code kompiliert (die virtuelle destructor Entfernen eines Übersetzungsfehler verursachen würde similar to the one you are seeing).

Wie richtig durch Luc Danton in den Kommentaren erwähnt, eine ausgefallene Version eines virtuellen Destruktor kann auf diese Weise definiert werden (wenn Ihr Compiler in dieser Hinsicht C++ 11-kompatibel ist):

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

@LucDanton: Richtig, ich habe vergessen, das zu erwähnen. Bearbeitet, danke –

3

Um eine dynamic_cast durchzuführen, muss der Typ, aus dem Sie gießen, polymorph sein. Damit dies zutrifft, müssen einige virtuelle Member vorhanden sein oder erben. Stellen Sie sicher, dass Event über eine virtuelle Memberfunktion verfügt (zumindest ein virtueller Destruktor).