Modularisierung - Zugriff auf ein Objekte in verschiedenen .cpp



  • Hallo zusammen!

    In dem, was ich bisher geschrieben habe, möchte ich eine .txt-Datei auslesen und die ausgelesenen Werte in ein Objekt speichern.

    Der Gedanke:
    Für jede neue Zeile aus der .txt, die einen "NeuenBefehl" darstellt, wird ein neues Objekt "Befehl" der Klasse "NeuerBefehl" angelegt, mit Werten gefüllt und in das Deque "Job_Liste" eingereiht. Über das Deque kann dann auf die verschiedenen Objekte und ihre Attribute zugegriffen werden. (Das alles passiert in Lesen.obj. Und innerhalb von Lesen.obj ist das auch kein Problem. Da funktiert alles so, wie ich mir das gedacht habe.)

    Nun möchte ich aber auch auf das Deque "Job_Liste" in anderen .cpp-Dateien zugreifen und mit dem Inhalt aus Lesen.obj arbeiten. Beispielsweise Rechenoperationen durchführen. Bei allem, was ich bisher versucht habe, verursache ich jedoch entweder einen Linker-Fehler, eine Ausnahme / schwerwiegenden Fehler oder sonst irgendwelche Errors;Packe ich die Definition in den Header, verstoße ich gegen die One-Definition-Rule (oder so). Versuche ich eine Übergabe über eine Funktion in ein zweites Deque, dass in der neuen .cpp definiert ist, bekomme ich einen schwerwiegenden Fehler. Es geht nicht vor und nicht zurück...

    Meine Frage: Was kann ich tun, um überall auf das Deque zuzugreifen? Ist Deque überhaupt die richtige Wahl? Für das Programm an sich wäre es schon sinnvoll, an einem Ort die Daten zu haben und dann von verschiedenen Orten darauf zuzugreifen...

    Hier etwas Code, um das Problem zu verdeutlichen:

    Lesen.cpp

     void Lesen() {										// Hauptfunktion des Moduls
    
    		//Datei wird geöffnet
    		datei.open("...");
    		//While-Schleife. Solange es Zeilen gibt, läuft sie durch
    		while (getline(datei, NeueZeile)) {
            /*Ganz viel Zeug
    	Am ende dann Speichern der durchgeführten Operationen*/
    			Speichern();
    //Erhöhen der Ordnungszahl bevor die Schleife von Neuem beginnt
    //orietiere mich damit innerhalb des Deques
    	Ordnungszahl++; 
    
    		}
    	}
    //Nun ein paar meiner Definitionen
    deque<NeuerBefehl> Job_Liste;						// Deque namens Job_Liste in dem die Werte von Befehl Stückweise gespeichert werden
    	NeuerBefehl Befehl;
    	
    void Speichern() {						
    		Befehl.Pos_Liste = Ordnungszahl;
    		Befehl.N_Line = dFeld[1];
    		Befehl.X_Achse = dFeld[2];
    		Befehl.Y_Achse = dFeld[3];
    		Befehl.Z_Achse = dFeld[4];
    
    		Job_Liste.push_back(Befehl);					
    	}
    
    	
    
    
    

    Lesen.h

    //Auszug aus Lesen.h
    
            int Ordnungszahl;
    	double dFeld[];
    
    		class NeuerBefehl {									// Die Klasse "NeuerBefehl" speichert am Schluss die produzierten Werte
    		public:												// und wird der Liste "Job_Liste" als neues Element hinzugefügt
    			int Pos_Liste = 0;
    			double N_Line = 0;
    			double X_Achse = 0;
    			double Y_Achse = 0;
    			double Z_Achse = 0;
    
    		};
    
    
    
    		void Lesen();										// Die Hauptfunktion dieses Moduls
    
    		void Zerlegung(string, int);						// Funktion zum Zerlegen des Strings
    
    		void Zuweisung(string);								// Zuweisung
    
    		void Speichern();								    // Speichert die Daten der Zerlegungs- und Zuweisungsoperationen
    
    void Test_Listenausgabe();
    

    Berechnung.cpp (Lesen.h ist über Berechnung.h inkludiert, was wiederum in Berechung.cpp ist)

    
    void Berechnung() {
    cout << Job_Liste.operator[](1).Pos_Liste << endl;
    //Kennt Job_Liste nicht. Packe ich die Definition in Lesen.h = Mehrfachdefinition
    
    }
    
    
    
    

    So: viel Gerede für eine kurze Frage 😃 Ich hoffe, ich habe alle relevanten Informationen zur Verfügung stellen können. Die Präprozessordirektiven habe ich einmal ausgelassen, da es da keine Probleme gab.

    Vielen Dank, ich freue mich über eure Hilfe und Antworten!
    JM



  • Globale Variablen sollte man eigentlich vermeiden!

    Aber um den Linker-Fehler zu beseitigen, mußt du in der dazugehörigen Headerdatei (also "Lesen.h") die Variable so deklarieren:

    extern std::deque<NeuerBefehl> Job_Liste;
    

    (und include <deque>hinzufügen)

    Und wäre es nicht besser (und schöner), wenn du die ganzen Variablen und Funktionen in eine passende Klasse packen würdest?



  • Moin @Th69 !

    Na toll, jetzt habe ich mich so viel geärgert und an alle möglichen Stellen extern eingefügt (bin in dem Buch, dass ich als Nachschlagewerk nehme, auch auf extern gestoßen, war mir aber über dessen Verwendung noch nicht ganz klar), nur nicht im Header. Ja, läuft!

    Ich hätte da noch eine Nachfrage zur globalen Variable. Das habe ich auch gelesen. Mich würde interessieren, welche Lösungen da noch infrage kämen. Letztendlich soll mit den Werten aus dem Deque an anderer Stelle weitergearbeitet werden. Also, wie wird sowas mehr "c++-like" gelöst? 🙂

    Vielen Dank für deine Hilfe! Ich werde auch mal schauen, wie ich alles noch schöner machen kann. Habe mich jetzt lang an diesem Problem aufgehalten 😃



  • @johnmoe sagte in Modularisierung - Zugriff auf ein Objekte in verschiedenen .cpp:

    Mich würde interessieren, welche Lösungen da noch infrage kämen.

    Parameter, Rückgabewerte, Membervariablen



  • Statt nur einzelne Befehle in einem Objekt zu organisieren wäre es eventuell sinnvoll eine übergeordnete Klasse anzulegen die sich um Lesen, Speichern, ablegen und entnehmen der Befehle kümmert.

    Der Code sähe dann z.B. so aus:

    class Befehle {
    public:
    	bool Speichern(int i, double n, double x, double y, double z);
    	bool Lesen(char *file_name);
    	bool Berechnung(int i);
    	size_t GetCount();
    
    private:
    	std::deque<NeuerBefehl*> m_jobliste;
    };
    
    .
    .
    .
    size_t Befehle::GetCount() {
    	return m_jobliste.size();
    }
    
    bool Befehle::Berechnung(int i) {
    	cout << m_jobliste.at(i)->N_Line << endl;
    	return true;
    }
    
    int main()
    {
    	Befehle liste;
    
    	liste.Lesen("befehle.txt");
    
    	int count = liste.GetCount();
    
    	for (int i=0; i<count; i++)
    		liste.Berechnung(i);
    
        return 0;
    }