... has not been declared



  • Hallo zusammen ich habe ein Problem:

    ich habe einen GNG_Algorithmus.
    Von diesem Algorithmus aus werden Nodes (einzelne Knoten) erstellt, sowie der NodePool. Der NodePool verwaltet alle existierenden Nodes und enthält auch eine Liste von allen existierenden Nodes.

    Es folgt die Klasse des Algorithmus: GNG_Algorithmus.h

    #ifndef GNG_ALGORITHM_H_
    #define GNG_ALGORITHM_H_
    
    #include "Node.h"
    #include "GNG_Parameters.h"
    #include "NodePool.h"
    
    class GNG_Algorithm
    {
    	void gng_Zero_StartWithTwoNodes(GNG_Parameters&, std::list<Node>&, NodePool&);
    }
    #endif /*GNG_ALGORITHM_H_*/
    

    Wenn ich nun bei diesem Algorithmus die Methode gng_Zero_StartWithTwoNodes(...) aufrufen möchte kommt immer der Fehler: „NodePool has not been declared“ wobei ich doch NodePool.h eingebunden habe.

    Dasselbe Problem habe ich wenn ich in dem NodePool einen Vector erstellen möchte, der Objekte vom Typ Node enthält. Wenn ich also ein Object vom Typ Node erstelle, soll der Nodepool diesen in seinen Vector aufnehmen. Aber im Nodepool kann ich auch keinen Vector erstellen, der Node Objecte enthält.
    Dann kommt dort auch „Node has not been declared“.

    Wisst ihr woran das liegen kann?

    Hier noch:

    NodePool.h

    #ifndef NODEPOOL_H_
    #define NODEPOOL_H_
    
    #include <vector>
    #include "GNG_Algorithm.h"
    #include "Node.h"
    #include "GNG_Parameters.h"
    
    class NodePool
    {
    public:
    	bool existingNodes[];		// contains for each possible node if its existing (true) or not (false)
    	std::vector<int> freeNodes;	// contains the ids of all free node positions in the nodelist
    	//std::vector<Node> nodelist;	// List Of all Nodes
    
    	NodePool(GNG_Parameters&);
    	virtual ~NodePool();
    
    	bool isNodeExisting(int);	//	to check if Node is valid
    	int getNextFreeNode(void);	//	to get Position to store next Node in array Nodelist
    	int setNextFreeNode(int);	// set the next id which is free for use to create new node
    
    };
    
    #endif /*NODEPOOL_H_*/
    

    und Node.h :

    #ifndef NODE_H_
    #define NODE_H_
    
    #include <iostream>
    #include <vector>
    #include <list>
    
    #include "NodePool.h"
    #include "GNG_Parameters.h"
    
    class Node
    {
    	int id_int;			// ID von Node
    	double error_dbl;
    	double position_dblary[];
    	std::vector<int> connections_vec;
    
    public: 
    
    	Node(void);
    	Node(GNG_Parameters&, std::list<Node>&);
    	~Node(void);
    
    	double createHazardValues();
    
    };
    
    #endif /*NODE_H_*/
    

    Vielen Dank und Grüße



  • redbomber schrieb:

    Wisst ihr woran das liegen kann?

    Daran, dass sich die Header gegenseitig einbinden. Das funktioniert nicht.

    Nimm einfach mal alle überflüssigen Includedirektiven raus.



  • MFK schrieb:

    redbomber schrieb:

    Wisst ihr woran das liegen kann?

    Daran, dass sich die Header gegenseitig einbinden. Das funktioniert nicht.

    Nimm einfach mal alle überflüssigen Includedirektiven raus.

    Und falls man das wirklich mal braucht. Stichwort: forward declaration.



  • drakon schrieb:

    MFK schrieb:

    redbomber schrieb:

    Wisst ihr woran das liegen kann?

    Daran, dass sich die Header gegenseitig einbinden. Das funktioniert nicht.

    Nimm einfach mal alle überflüssigen Includedirektiven raus.

    Und falls man das wirklich mal braucht. Stichwort: forward declaration.

    Und / Oder:

    Man baut eine Header-Datei die nur Includes enthält und lässt jedes CPP-File diese Datei includen. 🙂



  • it0101@loggedoff schrieb:

    Man baut eine Header-Datei die nur Includes enthält und lässt jedes CPP-File diese Datei includen. 🙂

    Wenn man unnötige Abhängigkeiten in den Source-Code einbauen will sicher.
    Beispiel: du implementierst eine neue Klasse, haust die in deinen Sammel-Header, und die .cpps von allen bis dahin implementierten Klassen müssen neu kompiliert werden, obwohl sie die neue Klassen garnicht verwenden - bei größeren Projekten bricht dir irgendwan der Rebuild das Genick...

    Lieblings-Link zu dem Thema:
    http://www.gotw.ca/gotw/007.htm



  • Die Frage ist, ob die Leute hier im Forum wirklich "große" Projekte haben.

    Also ich arbeite beruflich momentan an einem 20.000 Zeilen Projekt ( ist noch nicht viel ) und da stört der Rebuild noch nicht. Sind auch erst 40 Klassen...

    Aber man erspart sich dadurch eben viele Probleme.



  • it0101@loggedoff schrieb:

    Die Frage ist, ob die Leute hier im Forum wirklich "große" Projekte haben.

    Also ich arbeite beruflich momentan an einem 20.000 Zeilen Projekt ( ist noch nicht viel ) und da stört der Rebuild noch nicht. Sind auch erst 40 Klassen...

    Aber man erspart sich dadurch eben viele Probleme.

    Also mein Freizeitprojekt hat so um die 15'000 Zeilen..
    Das ist nicht wirklich gross. 🙄



  • Sag ich ja 🙂

    Und solange man in dem Bereich bleibt seh ich kein Problem in meiner Vorgehensweise. Wenns natürlich wirklich Richtung 100.000 oder mehr geht, sollte man auf sowas natürlich verzichten.



  • it0101@loggedoff schrieb:

    Die Frage ist, ob die Leute hier im Forum wirklich "große" Projekte haben.

    Also ich arbeite beruflich momentan an einem 20.000 Zeilen Projekt ( ist noch nicht viel ) und da stört der Rebuild noch nicht.... .

    Ein Rebuild ist auch nicht das Problem (bei heutigen Rechnerleistungen und der Möglichkeit, im Hintergrund zu kompilieren).

    Das Problem bei Abhängigkeiten liegt z.B. im "Modul-", "Komponenten-" oder gar "Programmgrenzen". Wir haben hier z.B. verschiedene "Basis-Komponenten", die von unterschiedlichen Programmen genutzt werden. Diese Programme haben unterschiedliche Kundenkreise und unterschiedliche Releasezyklen. Wenn ich nun alle Header in einen Topf werfe, bekomme ich bei jeder Änderung von Programm A auch von Programm B eine neue Version, die ich verwalten muss. (selbst, wenn ich sie per Versionierung "abschotte", habe ich sie trotzdem erzeugt und muss ggf. bei einer anderen Änderung in Programm B "mergen" oder "weiterführen" oder "auseinanderlaufen lassen".

    Es gibt schon genug Situationen, wo das unvermeidlich ist (wenn sich eine wirklich gemeinsam genutzte Funktionalität ändern soll) - da sollte man sich den Ärger nicht noch in den anderen Fällen antun.

    it0101@loggedoff schrieb:

    ...Aber man erspart sich dadurch eben viele Probleme.

    Eigentlich nicht. Man verschiebt sie nur - meistens in eine Phase, wo sie sehr viel mehr schmerzen.

    it0101@loggedoff schrieb:

    ...Und solange man in dem Bereich bleibt seh ich kein Problem in meiner Vorgehensweise. Wenns natürlich wirklich Richtung 100.000 oder mehr geht, sollte man auf sowas natürlich verzichten.

    Sobald sich "Strukturierung" (wie der Einsatz von Headern) überhaupt lohnt, sollte man sie auch vernünftig machen.

    Gruß,

    Simon2.


  • Administrator

    it0101@loggedoff schrieb:

    Die Frage ist, ob die Leute hier im Forum wirklich "große" Projekte haben.

    Also ich arbeite beruflich momentan an einem 20.000 Zeilen Projekt ( ist noch nicht viel ) und da stört der Rebuild noch nicht. Sind auch erst 40 Klassen...

    Aber man erspart sich dadurch eben viele Probleme.

    Erspart sich Probleme? Du meinst du schaffst dir unnötig Probleme?
    Vor allem gewöhnst du dich an etwas, das dir später zu einem Verhängnis werden kann.

    Ich arbeite auch nicht an grösseren Projekten als 10'000 bis 20'000 Zeilen, wobei man sich hier auch immer fragt, was zählt man alles als Zeile 😉
    Aber ich weiss etwas definitiv, wenn ich auch in so einem "kleinen" Projekt die Includes richtig setze, kann ich mehrere Sekunden Compilezeit einsparen, teilweise sogar eine halbe bis ganze Minute.
    Das Problem taucht erst recht in Code auf, wo du viele Templates einsetzt. Mach mal so einen Include-Header und nimm dort z.B. Boost.Spirit mit rein. Wenn der nun immer Boost.Spirit für jedes CPP-File mitparsen muss ... da kannst du eine gewisse Zeit warten 🙂

    Zudem ist es auch eine unnötige Überforderung an das IntelliSense oder ähnlichen Systemen.

    Grüssli



  • Bei uns liegt die Software eher im Bereich 10^6 Zeilen, vielleicht auch mehr (habe keinen Überblick über sämtliche Module). Vieles davon ist Java, aber einige Module bestehen größtenteils aus C/C++ Sourcen. Der Build der kompletten Software dauert ca. 20 Minuten.

    Bei einem Freund war es noch schlimmer, da haben sie durch Reduzieren der Compiletime-Abhängigkeiten ein reines C++-Programm von über 15 Minuten auf unter 10 Minuten Buildzeit drücken können. Um die Größenordnungen gehts aber nichtmal unbedingt, es geht vor allem darum dass man bei kleineren Änderungen die man testen möchte jedesmal erst ne Kaffeepause einlegen darf, weil der Build nicht nur ein oder zwei Klassen sondern ein komplettes Modul erfasst und statt 4 Sekunden 4 Minuten dauert - und sowas ist auch bei ~10k Zeilen durchaus normal.



  • Vielen Dank euch allen, hat nun alles geklappt. War mal ein dummer Fehler 😉


Anmelden zum Antworten