Linker Fehler unklar



  • Hallo

    Ich habe ein Linker Problem. Ich habe minimal eine Klasse Network erstellt und will diese in meiner main Funktion nutzen.

    Meine main Funktion:

    #include <iostream>
    #include "Network.h"
    
    using namespace std;
    
    int main(int argc, char** argv) {
    
    Network network; // Declare an object network with type Network
    cout << "Neurons: " << network._AdSize << endl;
    
    return 0;
    }
    

    Meine Klasse Network:

    Die Network.h Datei:

    #ifndef NETWORK_H
    #define NETWORK_H
    
    // A class for the network topology
    class Network {
      public:
       //Constructor
       Network(); 
    
       // Number of Neurons
       static int _AdSize;
    };
    
    #endif  // NETWORK_H
    

    Und die Network.cpp Datei

    #include "Network.h"
    
    // Constructor for the Network class.
    Network::Network() {
      _AdSize = 8;
    }
    

    Ich erhalte bei dem Befehl

    g++-5 -std=c++14 -Wall -g Main.cpp -o Programm
    
    undefined reference to `Network::Network()
    undefined reference to `Network::_AdSize'
    collect2: error: ld returned 1 exit status
    

    In der Network.cpp ist der Header inkludiert und in der main Funktion auch. Wo ist der Fehler?

    Danke und Grüße



  • Du musst den statischen Member auch noch definieren und damit initialisieren (im cpp-File). Damit ist die Zeile im Konstruktor überflüssig, weil sie vermutlich nicht das macht, was du erwartest.

    int Network::_AdSize = 8; 
    
    Network::Network() { 
    }
    

    Vermutlich sollte dieser Member auch const sein. Ausserdem sind Member-Bezeichner die mit Underscore und Grossbuchstaben beginnen problematisch, weil sie für den Compiler reserviert sind (etwas salopp ausgedrückt).

    // Edit

    Oder aber der Member sollte nicht static sein und du hast das nur gemacht, weil dir nicht bekannt war, was es genau bedeutet oder dir nicht klar war, wie du anschliessend darauf zugreifen kannst.



  • Warum static, wenn die Variable im Konstruktor gesetzt wird?



  • Der Fehler

    undefined reference to `Network::Network()'
    

    bleibt leider trotzdem 😞



  • cpp_Jungspund schrieb:

    Der Fehler

    undefined reference to `Network::Network()'
    

    bleibt leider trotzdem 😞

    Um diesen Fehler zu korrigieren musst du noch die Network.cpp Datei mitkompilieren.

    // Edit

    g++-5 -std=c++14 -Wall -g Main.cpp Network.cpp -o Programm



  • Hallo

    Estmal Danke, es läuft. Eine Fragen habe ich dazu noch:

    Ich habe nun in der header Datei der Klasse Network

    const int _AdSize = 4;
    

    gesetzt und in der cpp Datei zu Network den Konstruktor leer gelassen.

    In meinem Skript steht, dass man Membervariablen in der header Datei nicht einen Wert zuweisen soll, sondern die Zuweisung der Werte über den Konstruktor entsteht. Das ist ja nun im Widerspruch zu dem was ich gemacht habe. Aber es läuft... ist es trotzdem okay obige Zeile in die header Datei geschrieben zu haben? Was ist denn da guter Code, Zuweisung im Konstruktor oder in der Klasse und warum?

    Grüße



  • Man soll nicht oder man kann nicht? Begründung?



  • Hi manni66

    Das steht das man es nicht soll. Leider ohne weitere Begründung.



  • Eine Konstante per Zuweisung im Konstruktor zu initialisieren geht nicht. Besser ist unabhängig davon die Initialisierungsliste des Konstruktors. Die Begründung für das "soll nicht" müsste der Skripautor schon liefern.

    Dein Programm ist nach diesem Skript aber nicht korrekt im Sinne der selbst aufgestellten Regeln.



  • Nach etwas Recherche bin ich auf diesen Beitrag hier gekommen:

    http://www.cplusplus.com/forum/beginner/166090/#msg836782

    Jetzt weist er die Variable in der Main.cpp zu. Jetzt bin ich doch verwirrt.

    Geht es da evtl. darum wann der Schreiber des Codes bestimmen möchte wann Speicher zugewiesen wird? Beim Konstuktor bekommt der Compiler ja erst die Anweisung Bytes zu reservieren, wenn er zu Laufzeit aufgerufen wird und gibt sie später mit dem Destruktor wieder frei und bei einer Initialisierung von Anfang an ist der Speicher fest belegt. Geht es darum?

    Und wieso wird in dem Post oben in der main Datei und nicht in dem Header initialisiert?

    Danke und Grüße



  • Es ist nicht klar, was Du eigentlich möchtest. Kann es sein, dass in dem Skript statt Zuweisung vielleicht Initialisierung steht? Wie statische Variablen, also welche, die für eine Klasse gelten, initialisiert werden, wird oben schon gezeigt. In dem von Dir gezeigten Link geht es aber um eine globale Variable. Wenn Du eine Größe brauchst, die konstant für ein Objekt sein soll (aber verschieden für verschiedenen Objekte), dann musst Du sie im Konstruktor initialisieren, und zwar in der initialisierungsliste nach :, nicht im Code-Block. Soll sie aber für alle Objekte gelten: siehe oben.
    Oder willst Du eine globale Konstante? Dann kannst Du in der Header-Datei schreiben:

    constexpr int _AdSize =4;
    


  • Diesen Beitrag habe ich gebraucht. Danke "vatertag_gelaufen" 🙂


Log in to reply