Frage

Lassen Sie uns sagen, ich habe eine Basis Klasse und mehrere Abgeleitet Klassen. Gibt es eine Möglichkeit, ein Objekt zu einem der abgeleiteten Klassen, ohne die Notwendigkeit zu werfen, so etwas zu schreiben:


string typename = typeid(*object).name();
if(typename == "Derived1") {
   Derived1 *d1 = static_cast< Derived1*>(object);
}
else if(typename == "Derived2") {
   Derived2 *d2 = static_cast < Derived2*>(object);
}
...
else {
  ...
}
War es hilfreich?

Lösung

Nicht.

Informieren Sie sich über Polymorphismus. Fast jeder „dynamic cast“ Situation ist ein Beispiel für Polymorphismus implementiert zu kämpfen.

Wie auch immer Entscheidung Sie in dem dynamischen Guss machen wurde bereits gemacht. Nur delegiert die eigentliche Arbeit an die Unterklassen.

Sie links aus den wichtigsten Teil Ihres Beispiel. Die nützliche, polymorphe Arbeit.

string typename = typeid(*object).name();
if(typename == "Derived1") {
   Derived1 *d1 = static_cast< Derived1*>(object);
   d1->doSomethingUseful();
}
else if(typename == "Derived2") {
   Derived2 *d2 = static_cast < Derived2*>(object);
   d2->doSomethingUseful();
}
...
else {
  ...
}

Wenn jede Unterklasse implementiert doSomethingUseful, das ist alles viel einfacher. Und polymorph.

object->doSomethingUseful();

Andere Tipps

Sie können dynamic_cast und Test für NULL verwenden, aber ich würde stark Sehen Sie den Code Refactoring statt.

Wenn Sie eine Unterklasse spezifische Handhabung, Template-Methode hilfreich sein könnte, aber ohne zu wissen, was Sie achive sind versucht, es ist nur eine vage Vermutung.

Derived1* d1 = dynamic_cast< Derived1* >(object);
if (d1 == NULL)
{
    Derived2* d2 = dynamic_cast< Derived2* >(object);
    //etc
}

Ich habe die folgenden Methoden auf meinem Intelligenter Zeiger-Typ, Simulation C # ‚wird‘ und ‚wie‘:

template< class Y > bool is() const throw()
    {return !null() && dynamic_cast< Y* >(ptr) != NULL;}
template< class Y > Y* as() const throw()
    {return null() ? NULL : dynamic_cast< Y* >(ptr);}

Sie können dieses mit dynamic_cast tun, z:

if ( Derived1* d1 = dynamic_cast<Derived1*>(object) ) {
    // object points to a Derived1
    d1->foo();
}
else if ( Derived2* d2 = dynamic_cast<Derived2*>(object) ) {
    // object points to a Derived2
    d2->bar();
}
else {
    // etc.
}

Aber wie andere gesagt haben, Code wie dies kann ein schlechtes Design angeben, und Sie sollten in der Regel a href verwenden <= "http://www.parashift.com/c++-faq-lite/virtual-functions.html "rel =" nofollow noreferrer "> virtuelle Funktionen polymorphes Verhalten zu implementieren.

in der Regel ist dies ein Zeichen für ein schlechtes Design. Warum brauchen Sie, dies zu tun? Es könnte möglich sein, neu zu gestalten, so dass dies nicht erforderlich ist.

Was versuchen Sie, genau das zu erreichen? Nach meiner Erfahrung, Dinge wie diese sind ein Zeichen für schlechtes Design. Neu bewerten Ihre Klassenhierarchie, weil das Ziel des objektorientierten Designs machen Dinge wie dies nicht notwendig ist.

Ihr Beispiel wird nicht Port, weil das genaue Format des Namens () nicht angegeben. Sie könnten eine Reihe von dynamic_casts versuchen. Dynamic_cast gibt einen Null-Zeiger, wenn Sie den falschen Typ gegossen. Wenn Sie jedoch eine typeswitch wie diese tun, es ist etwas falsch mit Ihrem Design.

Ich denke, dynamic_cast ist der Weg zu gehen, aber ich glaube nicht, vor allem dies ein schlechtes Design für alle möglichen Bedingungen ist, weil Objekt gegossen wird etwas von einigen Dritt Modul zur Verfügung gestellt werden kann. Lassen Sie uns sagen Aufgabe durch ein Plug-in erstellt wurde, dass die Anwendung Autor keine Kenntnis hat. Und die besondere Plug-in kann Derived1 erstellen geben (die alte Version ist) Objekt oder Derived2 (wobei die neue Version) Typ-Objekt. Vielleicht war die Plug-in-Schnittstelle nicht versionsspezifische Dinge zu tun entworfen, es schafft nur das Objekt, so dass die Anwendung diese Art von Kontrolle tun muß richtige Gießen / Ausführung zu gewährleisten. Danach können wir nennen object.doSomethingUsefulThatDoesNotExistInDerived1 sicher ();

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top