Basisklasse in eine abgeleitete Templateklasse casten
-
Hallo
Von einer Basisklasse habe ich eine Templateklasse und eine normale Klasse abgeleitet.
Nun übergebe ich einer Funktion ein Objekt einer dieser beiden Objekte als Basisklasse.Nun möchte ich durch einen dynamic_cast (RTTI) feststellen um welche Klasse es sich handelt.
bool MyFunction(CBaseClass* base) { bool retval = false; CTemplateClass* tpl = NULL; CNormalClass* norm = NULL; if( tpl = dynamic_cast<CTemplateClass*>(base) ) retval = MyFunction(tpl); else if( norm = dynamic_cast<CNormalClass*>(base) ) retval = MyFunction(norm); else retval = false; return false; }
So nun erhalte ich allerdings einen Compilerfehler:
Zeile 5: Für die Verwendung der template-Klasse ist eine template-Argumentliste erforderlich.
Was muss ich hier angeben. Ich kenn ja den Typ nicht den ich als Parameter bekomme.
-
Du MUSST den genauen Typ kennen, bzw. solltest wohl die Basis Klasse benutzen.
Warum möchtest Du die Typen unterscheiden?Simon
-
Du MUSST den genauen Typ kennen, bzw. solltest wohl die Basis Klasse benutzen.
Kenn ich aber nicht. Das will ich ja mit RTTI heraus finden.
Warum möchtest Du die Typen unterscheiden?
Na weil verschiedene Funktionalitäten ausgeführt werden müssen.
-
MyClass<int> und MyClass<double> ist wie MyClassInt und MyClassDouble. Die haben keine Gemeinsamkeiten.
-
MyClass<int> und MyClass<double> ist wie MyClassInt und MyClassDouble. Die haben keine Gemeinsamkeiten.
???Was willst du mir damit sagen????
-
Templates generieren dir Klassen. Du hast für jeden Template Parameter eine neue Klasse erzeugt (bzw der Compiler). Es gibt keine Klasse CTemplateClass sondern CTemplateClass<T> Klassen - also CTemplateClass<int>, CTemplateClass<MyClass> oder was auch immer.
-
Schön und?
Du willst mir was sagen, es geht oder geht nicht?
-
Du hast von C++ offensichtlich keine Ahnung. Naja gut, OK, deswegen fragst du ja hier. Ein netterer Ton wäre aber auch ... nett.
Klare Antwort: nein, was du da machen willst geht so nicht.
Asserti schrieb:
Du MUSST den genauen Typ kennen, bzw. solltest wohl die Basis Klasse benutzen.
Kenn ich aber nicht. Das will ich ja mit RTTI heraus finden.
Warum möchtest Du die Typen unterscheiden?
Na weil verschiedene Funktionalitäten ausgeführt werden müssen.
Geht aber nicht. Ich gehe davon aus dass es sich um einen Design-Fehler deinerseits handelt.
Aber selbst wenn das Design OK sein sollte, wenn man es unabhängig von den Möglichkeiten die C++ bietet betrachtet (bzw. eben wie in diesem Fall: nicht bietet): es geht eben in C++ nicht, d.h. du musst es irgendwie anders machen.
Wie können wir dir aber auch nicht sagen, wenn du uns nicht sagst, was dein Beweggrund war, so etwas zu versuchen.
-
Du hast von C++ offensichtlich keine Ahnung
Na wenn du meinst
Klare Antwort: nein, was du da machen willst geht so nicht.
Also gut. Das ist doch eine Aussage. Dann mach ich es anders.
Ich gehe davon aus dass es sich um einen Design-Fehler deinerseits handelt.
Nur weil du es nicht verstehst, oder es nicht geht, muss es noch lang kein Design fehler sein.
-
-
Ich sehe das auch als Desingfehler.
Wenn es verschiedene Funktionen gibt, kannst Du zum Beispiel Interfaces erfragen die das Objekt zum Beispiel unterstützt, so wie es COM z.B. macht.
Jeden Typ in einem switch case und einem dynamic_cast zu prüfen halte ich für falsch.
Du findest übrigends nette Lösungen für solche Probleme in den "Design Patterns", oder auch in "Effective C++"
-
Hallo Martin
Wenn es verschiedene Funktionen gibt, kannst Du zum Beispiel Interfaces erfragen die das Objekt zum Beispiel unterstützt.
Hört sich interessant an. Kannst du mir das ein bischen näher erläutern. Habe ich noch nicht ganz verstanden.
Du findest übrigends nette Lösungen für solche Probleme in den "Design Patterns", oder auch in "Effective C++"
Das "Design Patterns" Buch habe ich. Da habe ich aber kein passendes Muster gefunden. Das "Effective C++" kannte ich noch gar nicht. Danke für den Tipp.
-
Bitte
-
Wenn es ein Designfehler ist das swith case, dann müsst es doch eine verständliche Lösung geben.
Vieleicht das Design zum besseren Verständnis:
Es beruht auf dem Composite MusterKlasse A -> Basisklasse / abstrakt
Klasse B -> abgeleitet von A / Templateklasse
Klasse C -> abgeleitet von AKlasse B enthält einen Wert vom typ T
Klasse C stellt eine Gruppe dar die wiederum Objekte von Klasse A (also B oder C) aufnehmen kann.Nun wird in einer Methode X einer weitere Klasse ein Objekt der Klasse A (also B oder C) übergeben.
So nun soll eine weitere Methode X aufgerufen werden. Diese ist nun abhängig ob es sich um ein Objekt der Klasse B oder um ein Objekt der Klasse C handelt.
Ich dachte nun das lässt sich mit Hilfe von RTTI lösen. Aber wie bereits festgestellt geht es nicht da es sich bei Klasse C um eine Templateklasse handelt.
Hoffe ich habe es verständlich ausgedrückt (nicht böse gemeint
)
Vieleicht könnt ihr mir nochmals helfen.
-
Asserti schrieb:
So nun soll eine weitere Methode X aufgerufen werden. Diese ist nun abhängig ob es sich um ein Objekt der Klasse B oder um ein Objekt der Klasse C handelt.
Es ist natürlich schwer etwas zu sagen, weil man nur einen kleinen Ausschnitt des Ganzen kennt. Das schreit doch nach einer virtuellen Methode - die evtl nochmal eine Referenz auf die aufrufende Klasse (die mit der Methode x) als Parameter hat.
-
Es ist natürlich schwer etwas zu sagen, weil man nur einen kleinen Ausschnitt des Ganzen kennt.
Jetzt habe ich doch schon extra weiter ausgeholt.
Alles andere ist überflüssig.
Das schreit doch nach einer virtuellen Methode
Was soll die Methode bewirken und wo soll die hin?
-
Asserti schrieb:
Es ist natürlich schwer etwas zu sagen, weil man nur einen kleinen Ausschnitt des Ganzen kennt.
Jetzt habe ich doch schon extra weiter ausgeholt.
Alles andere ist überflüssig.
Naja du musst es ja wissen.
Das schreit doch nach einer virtuellen Methode
Was soll die Methode bewirken und wo soll die hin?
Na in die Klasse A natürlich.
Weisst du was virtuelle Funktionen/Methoden sind?
Vermutlich nicht. Lies es nach, dann wirst du verstehen wie das mit einer virtuellen Funktion ganz einfach und ohne if/switch() geht.
-
Weisst du was virtuelle Funktionen/Methoden sind?
Ja stell dir mal vor. Egal.
Ich kann die Klasse A aber nicht erweitern. Ich weiß, wieso, weshalb, warum.Gibt es eine Lösung mit meiner Einschränkung?
-
Das Problem ist: Ich kann zwar die Basisklasse um eine Virtuelle Funktion erweitern. Aber wie soll ich das bitte die Funktion in den spzeiellen Templateklassen überschreiben. Diese sind nur Typdefs auf die Templateklasse.
typedef CClassB<bool> CBooleanVar; typedef CClassB<int> CIntVar;
-
Kopfschüttel. Dann mach Klassen draus:
class CBooleanVar : public CClassB<bool> { virtual void MyVirtualImplementation(); }; class CIntVar: public CClassB<int> { virtual void MyVirtualImplementation(); };
Im template CClassB wird dann die entsprechende pure virtuelle Funktion deklariert.