Ersetzbarkeit, Untertypen ?
-
Hi,
ich habe eine Klasse CTermin:
class CTermin { CTermin(const unsigned int datum, const unsigned int beginn, const unsigned int ende, std::vector <CRessource*> ressourcen) : m_datum(datum), m_beginn(beginn), m_ende(ende), m_ressourcen(ressourcen){} private: const unsigned int m_datum; const unsigned int m_beginn; const unsigned int m_ende; std::vector <CRessource*> m_ressourcen; };und davon eine Klasse CTerminG abgeleitet, die ein Memberattribut hinzufügt:
class CTerminG : public CTermin { public: CTerminG(const unsigned int datum, const unsigned int beginn, const unsigned int ende, std::vector <CRessource*> ressourcen, std::list <CMitarbeiterP*> teilnehmer) : CTermin(datum, beginn, ende, ressourcen), m_teilnehmer(teilnehmer) {} private: std::list <CMitarbeiterP*> m_teilnehmer; };So jetzt hab ich im meinem Programm öfters einen vector mit Terminen. Was muss ich jetzt tun um so einen vector sowohl mit <CTermin*>, als auch mit <CTerminG*> füllen zu können.
Ich komme einfach nicht dahinter, aber das muss doch möglich sein, oder?!sg,
soad
-
Dafür must du garnichts tun, das geht einfach so!?
wenn du jetzt methoden aus einem TerminG aufrufst müssen die natürlich in Termin auch existieren und (wichtig!) in terminG muss ein virtual davor, sonst wird die methode aus Termin ausgeführt (in Termin muss glaube ich auch ein virtual davor)
also zB:
virtual void getString() { ... }Aber wenn du eine list<Termin > hast kannst du die mit Termin und TerminG* füllen, garkein Problem (müssen aber pointer sein, vllt scheiterts daran?!)
-
Polymorphie nutzen:
vector<CTermin*> Temine; Termine.push_back(new Temin(...)); Termine.push_back(new TerminG(...));Wenn du auf spezifische Bestandteile der abgeleiteten Klasse zugreifen willst, mußt du den Wert per dynamic_cast<> umcasten (oder du definierst dir in der Basisklasse virtuelle Methoden für die nötigen Datenzugriffe).
-
Danke erstmals, aber ich kann´s leider nicht testen, weil ich mit dieser neuen Unterklasse CTerminG ein Spirale in meiner Include-Hierarchie habe. Bekomme immer den Fehler "fatal error C1014: Zu viele Headerdateien: Tiefe = 1024", weiss aber nicht wie ich das auflösen soll
.Habe folgende Include-Hierarchie:
CRessource -> CTermin -> CTerminkalender -> CMitarbeiter -> CMitarbeiterP(abstrakt) -> davon dann noch abgeleitet die speziellen Mitarbeitertypen.
Jetzt habe ich aber die Klasse CTerminG mit dem neuen Attribut der CMitarbeiterP-Liste, also habe ich dort CTermin & CMitarbeiterP inkludiert, aber wenn ich CTerminG auch in CTerminkalender inkludiere, dann habe ich diese Schleife :(.
Aber das muss ich doch eigentlich so machen, oder ?!?
-
Stichworte: Include-Guard und Forward-Deklaration
-
mmmh, #ifndef & #define hab ich eigentlich in jedem header-file. ich habs noch mit #pragma once versucht und die includes nach dem #define, aber das funktioniert alles nicht :(. könntest du mir bitte vielleicht noch einen tipp geben?!
-
Nachdem der Präprozessor durch ist, hat er die #includes in einer festen Reihenfolge (so, wie er sie gefunden hat) in deine Übersetzungseinheit zusammengefügt. Wenn du da eine ringartige Reihung aufgebaut hast, wird die entweder durchbrochen oder führt zu einer Endlos-Rekursion, die der Präprozessor irgendwann unterbricht. Die Lösung dazu lautet "Forward Deklaration" - solange du nur den Namen der Klasse benötigst, brauchst du nicht den kompletten Header, sondern "nur" ein (z.B.) 'class CMitarbeiterP;'.
(das reicht aus, um Zeiger oder Referenzen auf diesen Typ anzulegen oder ihn als Parameter/Rückgabewert einer Funktion anzugeben. In der zugehörigen CPP-Datei brauchst du dann die komplette Definition der Klasse)