2016-12-15 2 views
1

Ich hatte einen ersten Blick in Smart-Pointer und versuchen, es mit Polymorphie anzuwenden.Wie man Typcheck mit Smart-Pointers und Subclasses anwendet

Lets denken Sie an einer Eltern-Klasse Auto und Unterklassen Van, Estate, Cabrio, ....

ich eine Liste von Element-Typ Auto haben. Ich füge Objekte der Unterklassen ein.

std::list <Auto *> lst; 
lst.push_back (new Van()); 

Wenn ich es bekomme, wenn eine typecheck, um es anders zu behandeln.

Alter Code mit Raw-Pointers.

Auto *a = list.first(); // returns Auto* 
if (typeid (*a) == typeid (Van)) 
{ // do van things } 
... 

Das funktioniert.

Aber es ist nicht, wenn ich shared_ptrs auf jeder Ebene wechseln.

std::shared_ptr <Auto> a = list.first() 

typeid ist immer shared_ptr von Auto. Ich erwarte shared_ptr der Unterklasse.

Es funktioniert, wenn ich es mit dem Kern des smart-ptr mache.

Auto *p = a.get(); 
typeid (*p) // is Van if it is a Van 

Aber ich bin sicher, dass das nicht der eleganteste Weg ist. Wie geht das mit Smart-Pointers?

EDIT:

Ich muss

  • haben 1 Liste für alle Arten von Autos

  • wenn ich es herausnehmen handle es separat.

EDIT:

I ersetzt Polymorphismus mit den Wortunterklassen. Weil es nicht darum geht, eine Nachricht an ein Objekt zu senden, sondern über seinen Typ, sondern mehr über die externe Typisierung.

Vielen Dank für Hilfe, Chis

+5

Sie sich von 'typeid' befreien. Was auch immer du mit "typeid" machst, du machst es falsch. Richtig geschriebener C++ - Code verwendet nicht 'typeid', sondern virtuelle Methodenaufrufe. Was mit intelligenten Zeigern ganz gut funktioniert. –

+0

Bitte geben Sie Ihren Titel an, um Ihre Frage zu beschreiben. Viele Ihrer Titel listen nur kurz einige Sprachfunktionen auf. Ich kann nur ein paar gute von 42 sehen! –

+0

@SamVarshavchik Nun, am besten richtig geschrieben C++ :) – Yakk

Antwort

4

Verwenden dynamic_cast, nie typeid:

if (Van* item = dynamic_cast<Van*>(a)) { 
    item->doVanThings(); // do van things 
} //else try other casts 

Noch besser wäre Polymorphismus differenzierbare zu lassen, da Sie verwenden Polymorphismus sowieso schon:

class Auto { 
public: 
    virtual void doThings() = 0; 
}; 

class Van : public Auto { 
public: 
    void doThings() override { 
     // do van things 
    } 
}; 

class Estate : public Auto { 
public: 
    void doThings() override { 
     // do estate things 
    } 
}; 

class Convertible : public Auto { 
public: 
    void doThings() override { 
     // do convertible things 
    } 
}; 

std::list<std::shared_ptr<Auto>> lst; 
... 
std::shared_ptr<Auto> a = lst.first(); 
a->doThings(); 
+0

'doThings' sollte markiert werden' override' –

+0

Ahh, das ist wahr zu 'override' in C++ 11 zu verwenden und Chris hat es damit zu markieren. –

+0

Danke, es arbeitet mit std :: dynamic_pointer_cast. – chris01

Verwandte Themen