HI zusammen,
ich habe folgendes Problem:
Ich habe eine Klasse "BASETask" die als Element unter anderen ein Zeiger
auf ein Objekt dieser Basis-Klasse hat. Die Klasse "StandardTask" erbt
von "BASETask".
Jetzt ist es so, dass Klassen, die von BASETAsk erben, das Element
"pHeadTask" verwenden und Objekte dieser vererbten Klassen auf
Funktionen mit dem gerebeten Element Headtask aufrufen. Also
pHeadTask->getStrComment(). Diese Funktion gibt es aber in des
Basisklasse nicht, ergo Copile-Fehler. Wie müsste ich dass denn machen.
Eine Idee wäre, das Element pHeadTask virtuell zu machen und in jeder
abgeleiteten Klasse zu überschreiben. Schließlich muss pHeadTask immmer
ein Zeiger auf die Klasse selbst sein.
- dynamic_cast benutzen,
- eine Methode implementieren, die den HeadTask liefert und in geerbten
Klassen wieder überschrieben wird,
- ...
Oder mal beschreiben, was es werden soll.
Es soll ein Aufgabenplaner werden. Dabei ist jede Aufgabe ein Task. Es
gibt aber verschiedene Typen von Tasks.
1. Ein einfacher Task, mit dem man nur Aufgabenbäume erstellen kann:
Also ein Task (Aufgabe) die wiederum ggf. Unteraufgaben hat.
2. Ein etwas erweiterter Task, der sich auch seine Position in einer
Listbox merken kann. Damit kann man dann sowas wie im angehängten Bild
bauen (funktionierte auch schon vor der Aufteilung der Funktion in
verschiedene Klassen mit Vererbung)
3, Ein noch weiter erweiterter Task, der sich eine Priorität merken kann
und dann nach dieser sortiert in einer Listbox erscheinen kann.
Im Prinzip ist also das Konstrukt so, dass jede Instanzierbare Klasse in
dieser Vererbungshierarchy Zeiger auf sich selbst haben muss. Wenn der
Zeiger nämlich vom Typ Basisklasse ist und ich Funktionen einer
vererbten Klasse damit aufrufen will, kracht es ja, wie beschrieben.
Ich danke für eure Antworten
Rainer Hohn schrieb:> Im Prinzip ist also das Konstrukt so, dass jede Instanzierbare Klasse in> dieser Vererbungshierarchy Zeiger auf sich selbst haben muss.
Da ist vermutlich ein Konzeptfehler.
Jede Klasse hat schon einen Zeiger auf sich selbst: Er heißt 'this'.
Ich denke, du willst in der Basisklasse eine virtuelle Methode anlegen,
die dann in den Ableitungen überschrieben wird. Das spart auch diese
seltsame Konstruktion mit dem pHeadTask.
Nein, so seltsam ist mein Konstrukt nicht...ist eine ganz normale
Verkettete Liste. Der this-Zeiger ist ja ein Zeiger auf das OBJEKT, bei
verketteten Listen brauche ich aber zwingend einen Zeiger auf den
gleichen (Klassen)-TYP.
Rainer Hohn schrieb:> Nein, so seltsam ist mein Konstrukt nicht...ist eine ganz normale> Verkettete Liste. Der this-Zeiger ist ja ein Zeiger auf das OBJEKT, bei> verketteten Listen brauche ich aber zwingend einen Zeiger auf den> gleichen (Klassen)-TYP.
Dann ist es aber kein Zeiger auf sich selbst sondern ein Zeiger auf ein
anderes Objekt aus derselben Klassenhierarchie.
Aber auch da: Wenn alle Objekte eine Methode anbieten sollen, mach sie
in deren Basisklasse virtuell und überschreibe sie dann.
Wenn du aber Methoden brauchst, die nicht alle Objekte haben, sondern
nur einige bestimmte, dann wäre das wohl ein Fall für den dynamic_cast.
Dabei aber den Fehler abfangen, denn möglicherweise lässt sich nich
jedes Objekt in das gewünschte Objekt casten.
Verkettete Listen gibt es außerdem schon fertig in der STL. Gibt
sicherlich auch ein Pendant dazu für den CLI-Blödsinn.
Ok dynamic cast hatte ich auch im Hinterkopf, ich wusste aber nicht, ob
das die feine Enlische Art ist, oder ob es da nicht ein ganz elegantes
C++-Konstrukt gibt, das ich nicht kenne.
Falls es das also nicht geben sollte, werde ich dynamic cast verwenden.
Vielen Dank schonmal an Sven
Rainer Hohn schrieb:> ob es da nicht ein ganz elegantes C++-Konstrukt gibt
Da Du nicht in C++ programmierst, kann Dir da auch kein C++-Konstrukt
helfen.
"C++/CLI" ist kein C++, sondern eine Microsoft-Perversion für .Net.
Naja, in irgendeiner Weise muss es ja auf RTTI hinauslaufen: Du
speicherst einen Zeiger auf eine Basisklasse. Und von dem möchtest du an
eine Ableitung herankommen...
Zur Elternklasse gehts (fast) immer, zu abgeleiteten Klassen könnte es
schiefgehen, daher RTTI/dynamic_cast. Keine Ahnung, ob das mit CLI auch
geht.
Rufus Τ. Firefly schrieb:> Rainer Hohn schrieb:>> ob es da nicht ein ganz elegantes C++-Konstrukt gibt>> Da Du nicht in C++ programmierst, kann Dir da auch kein C++-Konstrukt> helfen.>> "C++/CLI" ist kein C++, sondern eine Microsoft-Perversion für .Net.
Auch durch Wiederholung wird das nicht "wahrer",
http://www.gotw.ca/publications/C++CLIRationale.pdf
"C++/CLI’s mission is to provide direct access for C++ programmers to
use existing CLI libraries and create new ones, with little or no
performance overhead, with the minimum amount of extra notation, and
with full ISO C++ compatibility."
Man könnte sich höchstens streiten, ob das nun mathematisch eine
Obermenge ist oder nich.
Einsetzen würde ich es für die Aufgabe hier allerdings definitiv nicht,
sondern nur da wo es sinnvoll ist (performance/native code/C++ interop)
Arc Net schrieb:> C++/CLI’s mission is to provide direct access for C++ programmers to> use existing CLI libraries and create new ones
Warum muss man eine Sprache abändern, um Zugriff auf gewisse
Bibliotheken zu erhalten? Leuchtet mir irgendwie nicht ein. Wer C++
will, soll halt auch C++ verwenden.
Wer hingegen .NET haben will, der kann doch auch gleich C# verwenden.
Die Sprache ist ja nicht mal schlecht designed. Da war ja der Anders
Hejlsberg am Werk, den man mit viel Geld abgeworben hat, weil man in den
eigenen Reihen offenbar keine fähigen Leute für sowas hatte :)