polymorphismus
-
servus!
ich habe eine pure virtual class IObject:namespace App { class IObject { public: virtual const char* toString() = 0; }; }
und die klasse Dateibaum
namespace App { namespace Tools { class FileTree : public IObject { public: virtual void toString(); virtual void add( std::string &text ); }; } }
und zu letzt die datai main:
int main() { IObject * obj = new FileTree(); obj->add("test"); // hier der fehler }
warum geht das nicht?
danke
-
Weil in deiner abstrakten Klasse 'add' nie erwähnt wird und C++ nach dem Simula-Prinzip und nicht wie Smalltalk arbeitet.
-
bin mir nicht 100% sicher, aber FileTree ist doch von Object abgeleitet, also kann filetree die Methoden von Object verwenden, aber nicht umgekehrt. Du versuchst aber, dass eine Object Instanz eine Methode von FileTree aufrufen solll.
Wie sieht denn die Fehlermeldung aus?
-
(dynamic_cast kann dir hier helfen)
-
Schon, aber für mich sieht es so aus, als habe er lediglich vergessen die entsprechende Deklaration in IObject zu packen. Aber um das herauszufinden müssen wir auf "problem mit" warten.
-
Ich glaube, dass er nicht will, dass die add-Methode in IObject steht.
-
Außerdem sollte der Parameter "const std::string&" sein, sonst geht add("blub") auch weiterhin nicht. Und der Rückgabewert von toString() sollte wohl nicht void sein. Außerdem hoffe ich, dass du den virtuellen Destruktor nur der Lesbarkeit halber gekürzt hast
-
Also ich seh da ein Fehler der gar nichts mit Polymorphy zu tun hat.
Man kann kein char* zu einer string& casten, (auf welches Object sollte denn Referencirt werden?) Mach aus der Referenze eine Klasse und dann baut der Copykonstruktor dir ein string.
-
Bin mir nicht sicher, denke aber, dass manche Compiler meckern werden, wenn du den Rückgabetyp von toString von const char* nach void umbaust.
oder was denkst du, wenn du folgendes schreibst:
void function(IObject* param) { static char Herribert = param->toString(); }
Ich denke, dass das nicht geht
mfg
Glamdring
-
hubs, das hat Optimizer schon gesagt, naja doppelt hält besser
mfg
Glamdring
-
Mal ne blöde Frage:
Wieso überhaupt...IObject * obj = new FileTree(); // ... und nicht ... FileTree * obj = new FileTree();
???
-
CarstenJ schrieb:
Mal ne blöde Frage:
Wieso überhaupt...IObject * obj = new FileTree(); // ... und nicht ... FileTree * obj = new FileTree();
???
Weil FileTree polymorph verwendet werden soll? Stell dir zB mal eine Factory vor.
-
Möglicherweise steck ich nicht tief genug in der Materie drin, also bitte um nähere Erklärung, falls ich etwas falsch verstanden habe.
Bei der Klasse IObject handelt es sich doch um eine Interface-Klasse.
Da die Klasse abstrakt ist, muss eben in diesem Fall FileTree die Methode toString() implementieren. Soweit hab ich das verstanden...Aber ist...
IObject * obj = new FileTree();
...nicht ein Upcast, der im Grunde aussagt, dass FileTree ein IObject ist?
-
CarstenJ schrieb:
...nicht ein Upcast, der im Grunde aussagt, dass FileTree ein IObject ist?
Jo, n upcast. Und die gehen ja 'implizit'.
nimm zB, folgendes konkretes Beispiel:
void writeToCout(IObject const& obj) { cout<<obj.toString(); } FileTree f; writeToCout(f);
-
Ja, aber das wäre doch nur der Fall, wenn die Methode add auch in der Basisklasse deklariert worden wäre?! Wenn das nicht der Fall ist, ist FileTree nicht vom Typ IObject.....und was jetzt eigentlich geplant war, wissen wir ja nicht, weil der sich der Threadersteller nicht dazu geäussert hat.
-
Ja, aber das wäre doch nur der Fall, wenn die Methode add auch in der Basisklasse deklariert worden wäre?! Wenn das nicht der Fall ist, ist FileTree nicht vom Typ IObject.....und was jetzt eigentlich geplant war, wissen wir ja nicht, weil der sich der Threadersteller nicht dazu geäussert hat.
HÄ??? Besoffen? Was soll der quatsch?
-
Wo ist denn jetzt dein Problem, du Held?
-
Ja, aber das wäre doch nur der Fall, wenn die Methode add auch in der Basisklasse deklariert worden wäre?! Wenn das nicht der Fall ist, ist FileTree nicht vom Typ IObject...
Ich verstehs auch nicht.
FileTree ist ein Typ und Typen sind normalerweise nicht "von einem Typ", auch nicht vom Typ IObject. Das ergibt einfach überhaupt keinen Sinn. Was hat die Methode add mit dem Typ zu tun?
-
Dann hab ich das eben falsch ausgedrückt. Was ich meinte bezog sich auf den Code von Shade:
void writeToCout(IObject const& obj) { cout<<obj.toString(); } FileTree f; writeToCout(f);
Die Funktion writeToCout erwartet einen Parameter vom Typ IObject, es wird aber ein Objekt FileTree übergeben. Da FileTree von IObject erbt, hat es die gleichen Schnittstellen wie IObject, welche eben nur anders implementiert werden. Falls was falsch ist, einfach berichtigen...
Da die Methode add aber in IObject nicht deklariert wurde, haben die beiden Klassen eben nicht die gleiche Schnittstellen......also kann man doch auch kein FileTree übergeben, wenn ein IObject erwartet wird. Oder?
-
CarstenJ schrieb:
Da die Methode add aber in IObject nicht deklariert wurde, haben die beiden Klassen eben nicht die gleiche Schnittstellen......also kann man doch auch kein FileTree übergeben, wenn ein IObject erwartet wird. Oder?
zB so:
void f(IObject& o) { o.add("muh"); }
Jo, das geht nicht. Denn IObject hat kein add(). Aber mit toString statt add würde es gehen.
Ich verstehe deinen Punkt einfach nicht...