2009-12-31 10 views
5

Wenn ich richtig verstehe, kann Typeid den tatsächlichen Typ in Polymorphie bestimmen, während Typeof nicht kann.Get Typ der Variablen

Ist es auch wahr, dass ihre Rückgaben für verschiedene Zwecke verwendet werden: Die Rückgabe von typeof wird als Typschlüsselwort verwendet, das Variable definieren kann, aber die Rückgabe von typeid kann nicht?

Gibt es eine Möglichkeit, sowohl den tatsächlichen Typ für Polymorphismus zu erhalten, als auch das Schlüsselwort return als Typ, um eine andere Variable zu definieren? Ich hoffe, den abgeleiteten Klassentyp aus einem Zeiger zu erhalten, der auf die Basisklasse zeigt, und eine Variable oder einen Zeiger auf die abgeleitete Klasse zu definieren. Etwas wie:

baseclass *p = new derivedclass 
typexxx(*p) *pp = dynamic_cast<typexxx(*p) *> (p); 
// would like to convert the pointer from pointing to a base class 
// to its derived class 

Vielen Dank!

+6

Können Sie ein Beispiel dafür geben, warum Sie dies tun möchten? Der Hauptpunkt einer Vererbungshierarchie ist, dass Sie normalerweise den tatsächlichen Typ nicht kennen müssen. –

+0

Ich möchte nur auf einige Member verweisen, die in der abgeleiteten Klasse, aber nicht in der Basisklasse definiert sind. Ich bin mir nicht sicher, ob es sinnvoll ist, der Basisklasse Elementfunktionen mit demselben Namen wie der abgeleiteten Klasse hinzuzufügen und sie als virtuell zu deklarieren, da diese Elementfunktionen zu spezifisch für diese bestimmte abgeleitete Klasse sind und in anderen nicht benötigt werden abgeleitete Klassen, und die Basisfunktion wird größer, wenn ich sie hinzufüge. – Tim

+1

OK, Sie können tun, was Sie mit dynamic_cast wollen, aber Sie müssen eine IF-Leiter verwenden, um die Zeiger des abgeleiteten Typs zu erstellen. –

Antwort

7

c++0x wird decltype haben, die wie folgt verwendet werden kann:

int someInt; 
decltype(someInt) otherIntegerVariable = 5; 

aber für plain old C++ leider nicht.

Ich nehme an, dass decltype wird nicht wirklich viel Hilfe entweder obwohl Sie den polymorphen Typ, nicht den deklarierten Typ wollen. Der einfachste Weg, um zu tun, was Sie wollen, ist zu versuchen, dynamisch auf einen bestimmten Typ zu werfen und nach NULL zu suchen.

struct A { 
    virtual ~A() {} 
}; 
struct B : public A {}; 
struct C : public A {}; 

int main() { 
    A* x = new C; 
    if(B* b_ptr = dynamic_cast<B*>(x)) { 
     // it's a B 
    } else if(C* c_ptr = dynamic_cast<C*>(x)) { 
     // it's a C 
    } 
} 
+0

Danke Evan! Aber manchmal muss ich den Typ zur Laufzeit wie über Befehlszeilenargument bestimmen. Siehe meinen Beitrag hier http://stackoverflow.com/questions/1984492/runtime-determine-type-for-c, du wirst es verstehen. – Tim

+0

'if (B * b_ptr = dynamic_cast (x))' und keine Notwendigkeit für entweder die Union oder mis-scoped Variablen. Außerdem kannst du noch mehr natürlich schreiben 'else if' anstatt' else {... if ...} ' –

+0

@Roger: Du lernst jeden Tag etwas Neues, ich wusste nicht, dass du Variable in einer if-Anweisung deklarieren kannst. und in einem angemessenen Umfang resultieren. Ich werde meine Antwort aktualisieren. –

3

Unter der Annahme einer Hierarchie < A - B < - C

A * p = new AorBorC; // create new object of some sort 

if (dynamic_cast <C*>(p)) { 
    C * c = dynamic_cast <C*>(p); 
    c->CFunc(); 
} 
else if (dynamic_cast <B*>(p)) { 
    B * b = dynamic_cast <B*>(p); 
    b->BFunc(); 
} 
else if (dynamic_cast <A*>(p)) { 
    A * a = dynamic_cast <A*>(p); 
    a->AFunc(); 
} 

Wo AFunc, BFunc, CFunc zu ihren jeweiligen Klassen spezifisch sind, und nicht virtuell. Offensichtlich kann dies etwas optimiert werden.

+0

'if (C * c = dynamic_cast (p)) {/ * benutze c * /}' Keine Notwendigkeit, zweimal zu werfen. –

+1

Ziemlich - Ich versuchte, die Dinge klarer zu machen, indem ich langatmig war. –