Problem mit Vererbung und zirkulierenden Abhängigkeiten



  • Hi,
    ich mache für die Uni gerade ein Projekt. Dazu muss ich 2 einfach verkettete Listen implementieren. Die erste nutzt die Struktur EElement als ihre Elemente und die zweite soll AElement nutzen.

    Das hab ich bereits:

    #include <string>
    #include <time.h>
    // Bearbeitungsstati für die Activities
    enum Status {created, working, done};
    
    // Nutzdaten für die EList (Editoren-Liste)
    struct Editor
    {
        std::string Name;
        int Alter;
    	bool	operator==(Editor ed);
    	bool    operator!=( Editor ed);
    };
    
    // Nutzdaten plus Verwaltungsdaten für EList
    struct EElement
    {
        Editor  Val;        // Nutzdaten
        EElement *Next;     // Verwaltungsdaten (Zeiger auf naechstes Element)
    };
    
    // Editoren Liste
    class EList
    {
    	public:
    		EList();
    		~EList();
    
            bool    m_IsEmpty(void);        // prueft ob Liste leer ist
            void    m_Insert(Editor v);     // fuegt Element in Liste ein
            Editor  m_Head(void);           // gibt neuestes Element zurueck
            bool    m_IsIn(Editor v);       // Prueft ob ein Element enthalten ist
            int     m_GetIndex(Editor v);   // Gibt Index einen Elementes zurueck
            Editor  m_GetElement(int pos);  // Gibt Element-Daten anhand ihres Index zurueck
            bool    m_Remove(Editor v);     // Loescht ein Element
    
    	private:
    		EElement *m_pFirst;                 // Zeiger zum neuesten Element
    };
    
    // **********************************
    
    struct Activity
    {
    	std::string description;    //Beschreibung
    	EList       editors;        //Bearbeiter dieser Activity (List of Editors)
    	time_t      dueDate;        //Faelligkeitsdatum
    	int         expenditure;    //Arbeitsaufwand (Stunden)
    	Status      state;          //Status [created,working,done]
    	AList       childs;         //Unteractivities (List of Integer)
    };
    
    struct AElement
    {
        Activity Val;       // Nutzdaten
        AElement *Next;     // Verwaltungsdaten (Zeiger auf naechstes Element)
    };
    
    // Aktivitaeten Liste
    class AList
    {
    	public:
    		AList();
    		~AList();
    
            bool        m_IsEmpty(void);        // prueft ob Liste leer ist
            void        m_Insert(Activity v);   // fuegt Element in Liste ein
            Activity    m_Head(void);           // gibt neuestes Element zurueck
            bool        m_IsIn(Editor v);       // Prueft ob ein Element enthalten ist
            int         m_GetIndex(Editor v);   // Gibt Index einen Elementes zurueck
            Activity    m_GetElement(int pos);  // Gibt Element-Daten anhand ihres Index zurueck
            bool        m_Remove(Editor v);     // Loescht ein Element
    
    	private:
    		AElement    *m_pFirst;              // Zeiger zum neuesten Element
    };
    

    Das sind nun meine Probleme:

    • EList und AList sind sich ja sehr ähnlich. Wie kann ich sinnvoll diese getrennte Imlementation zusammenfassen?
    • die Struktur Actitivity besitzt ein Element vom Typ AList[i] für ihre Unteraktivitäten (wodurch eine Baumsturktur entsteht). Aber [i]AList wird ja erst später deklariert. Wie löse ich das Problem?

    Mfg Michael



  • Hi,
    Du kannst Templates benutzen, um eine allgemeine verkettete Liste zu erstellen.
    z.B.

    template <class T>
    class LinkedList
    {
        struct Element
        {
            T data;
            Element *pnext;
        };
        Element *pfirst;
        public:
        //Die Element Funktionen
        void insert(const T &newelement);
        //usw
    };
    
    template <class T>
    void LinkedList<T>::insert(const T &newelement)
    {
      //...
    }
    
    class Activity
    {
        LinkedList<Activity> list;
    };
    
    class Editor
    {
    };
    
    //Dann kannst du auch sowas machen
    typedef LinkedList<Activity> AList;
    typedef LinkedList<Editor> EList;
    
    int main()
    {
        AList activitylist;
        EList editorlist;
    }
    

    Tschau,
    Cappo



  • Ich glaub ich hab soweit alles hinbekommen aber in meiner main.cpp meckert er unverständlichers Weise noch rum:

    undefined reference to `TLinkedList<CEditor>::TLinkedList>'

    Und das für jede Funktion die ich in der main.cpp aufrufe.

    Allerdings hab ich die meine list.h eingebunden und in list.h und list.cpp ist alles soweit richtig. Dort meckert er auch nicht mehr.

    Kapier das nicht ganz 😕

    Hier hab ich mal den Source abgelegt - ihn zu posten wäre zu unübersichtlich geworden.

    List.h
    List.cpp
    Main.cpp



  • Also wenn ich alles aus der List.h und List.cpp in die main.cpp kopiere ist der fehler verschwunden. Da frag ich ich aber wieso - eigentlich hab ich die dateien doch richtig eingebunden 😕



  • Hi,
    wenn sonst keiner antwortet mach ich es halt 😉 .
    Die Templatedefinitionen müssen mit in den Header.
    Es gibt zwar das Schlüsselwort export mit dem es möglich sein sollte Templates in .h und .cpp aufzuteilen,allerdings wird dieses von keinem mir bekannten Compiler unterstützt.
    Und selbst wenn deiner das unterstützen sollte fährst du mit dem altbekannten Schema trotzdem besser weil dein Code dadurch portabler bleibt.
    Durchsuch mal das Forum,da wirst du schätzungsweise 1 Milliarde Posts zu dem Thema finden.

    Gruss Spacelord



  • Und wenn's sonst keiner sagt, dann halt ich: Die gezeigt Lösung paßt nicht zur Aufgabenstellung. Die Liste soll die angegebenen Klassen als Nodes verwenden und nicht die nochmal in Nodes verpacken. Wozu wären sonst die next* gut?

    Kann man natürlich trotzdem über ein template machen, allerdings müßte dann der NodeTyp der template-Parameter sein, nicht der Datentyp. Ist halt eine intrusive List.



  • Die Aufgabenstellung ist eine ToDo Liste zu implementieren - ich hab für mein hier beschriebenes Problem nur das relevante zusammen gefasst. 🙂


Anmelden zum Antworten