undefined reference



  • hi leute

    hatte mir vor einiger zeit eine kleine klasse geschrieben, die mir eine 7-segment anzeige einer eingelesenen zahl macht. diese klasse wurde natürlich schulbuchmässig in .hpp und .cpp files aufgeteilt! 🙂

    nun möchte ich mit dieser klasse etwas mehr anstellen und schreibe mir eine weitere, neue klasse, genannt "Digit".
    In dieser klasse möchte ich die funktionalität von siebenSegment (die 'alte' klasse) erweitern und frage mich deshalb, wie ich das am besten anstelle *ohne* zuhilfenahme von vererbung?

    meine idee wäre jetzt gewesen, dass ich das .hpp-file der siebenSegment-Klasse in meine neue klasse includiere und somit mit einer variablen zugreifen kann.
    anschliessend möchte ich die digit-klasse um neue funktionalitäten erweitern und das erstellte siebenSegment-Objekt dazu zu benutzen, dass die Zahl angezeigt wird. die klasse siebenSegment hat eine Funktion, welche mir die eingegebene zahl in 7-segment anzeigt

    wenn ich nun im main des digit-projekts ein 'siebenSegment s' machen möchte, meckert der compiler.
    untenstehend code und die fehlermeldung.

    Beispiel:

    int main(){
    	Digit d; // Anlegen eines Digit-Objekt
    	siebenSegment s;  // dies funzt ned
            // Fehlermeldung ist: 'undefined reference to `siebenSegment::siebenSegment()'
    
    }
    

    nun ist mir nicht ganz klar, warum das nicht funktionieren soll? 😕

    könnte mir hier kurz jemand erklären, warum das nicht geht?

    mfg
    rox



  • Du hast die compilierte Objektdatei von siebenSegment.cpp (oder der Datei wo die Klasse enthalten ist) nicht mitgelinkt.



  • Wie genau ist denn die Beziehung zwischen der Anzeigeklasse und deiner neuen Digit-Klasse? Irgendwie werde ich aus deiner Beschreibung nicht so recht schlau.

    (Außer Vererbung kannst du auch noch Membervariablen in deiner Digit-Klasse nutzen - passt wohl am besten, wenn du die Methoden der Anzeige verwenden willst, um eine Ziffer darzustellen)



  • hey

    danke für die schnell antwort!
    hat alles gefunzt! 🙂

    mfg
    rox



  • hi cstoll

    nun, es herrsch eigentlich noch gar keine beziehung, die möchte ich ja eben mit dem includieren herstellen, sprich ich möchte objekte der siebenSegment-Klasse in meiner neuen Digit-Klasse erstellen können.

    mit dem vorschlag des includieren des files, in welchem die klassendefinition steht, hat es funktioniert aber ich denke, es gibt noch weitere möglichkeiten, nicht?

    wie meinst du das genau mit der membervariable?



  • Das Inkludieren des Headers (zusammen mit dem passenden Objektfile) ist nur der erste Schritt - danach kannst du irgendwo in deinem Programm Objekte der Klasse "siebenSegment" anlegen und deren Methoden ansprechen. Das mußt du auf jeden Fall machen, wenn die Klassen irgendwie zusammenarbeiten sollen.

    Der nächste Punkt ist das Design - in welcher Beziehung stehen die Klassen "siebenSegment" und "Digit" zueinander? Davon hängt es dann ab, wo du dein Anzeige-Objekt anlegst und von wo aus du darauf zugreifen willst. Darüber solltest du dir also noch Gedanken machen.

    wie meinst du das genau mit der membervariable?

    Damit meinte ich, daß jedes Digit-Objekt selber verwalten sollte, zu welchem siebenSegment-Objekt es gehört:

    class Digit
    {
    public:
      Digit(siebenSegment* anz,...)
      : anzeige(anz),...
      {}
    private:
      siebenSegment* anzeige;//Pointer auf Display-Objekt
    };
    


  • hey leute

    also irgendwie funzt momentan gar nix mehr, obwohl ich echt keine ahnung hab warum? (programmiere erst seit märz mit C++, daher die vielen fragen...)

    folgendes: als ich heute nachmittag das ganze mit dem includieren der beiden .cpp und .hpp der siebenSegment-Klasse in meiner Digit-Klasse gemacht hab, hats gefunzt. Nun weiss ich nicht (kann mich nicht erinnern), dass ich daran was geändert hätte, denn momentan funktionierts gar nicht mehr.

    Der Compiler kommt mit der Fehlermeldung, dass die beiden Methoden in meiner siebenSegment-Klasse bereits definiert wären? Diese Meldung erscheint allerdings nur, wenn ich die Digit-Klasse versuche zu compilieren. Wenn ich das Projekt siebenSegment compiliere, läuft alles wunderbar.
    Es muss daher etwas mit dem Linkvorgang zu tun haben.

    Zwischendurch hab ich versucht, die .o-Datei auch mittels #include einzubinden. Hat aber nicht geklappt, da kamen noch seltsamere Meldungen des Compilers, daher schliesse ich, dass dies nicht so gemacht werden kann?!

    Weiss da vielleicht grad jemand abhilfe oder hat jemand ne Idee, an was es liegen könnte? Danke fuer eure Hilfe!

    mfg
    rox

    /edit
    Seltsamerweise zeigt es mir beim siebenSegment-Projekt (arbeite mit Eclipse) ebenfalls einen Fehler an, wenn ich versuche die Digit-Klasse zu compilieren. Wenn ich dann anschliessen aber wieder die siebenSegment-Klasse alleine kompiliere, erscheint kein Fehler...

    Hier mal ein paar Fehler:

    ../../UebW4_Aufgabe3/Debug/siebenSegment.o:3: error: stray '\4' in program
    ../../UebW4_Aufgabe3/Debug/siebenSegment.o:3: error: stray '\199' in program
    ../../UebW4_Aufgabe3/Debug/siebenSegment.o:3: error: stray '\133' in program
    ../../UebW4_Aufgabe3/Debug/siebenSegment.o:3: error: stray '\255' in program
    ../../UebW4_Aufgabe3/Debug/siebenSegment.o:3: error: stray '\255' in program
    ../../UebW4_Aufgabe3/Debug/siebenSegment.o:3: error: stray '\255' in program
    ../../UebW4_Aufgabe3/Debug/siebenSegment.o:3:1215: warning: null character(s) ignored
    ../../UebW4_Aufgabe3/Debug/siebenSegment.o:3: error: stray '\232' in program
    ../../UebW4_Aufgabe3/Debug/siebenSegment.o:3:1220: warning: null character(s) ignored

    /edit2
    Ich arbeite in der siebenSegment-Klasse mit boost. Muss ich diese in meiner Digit-Klasse ebenfalls einbinden, wenn ich die .cpp und .hpp files einbinde? Oder wird das automatisch gemacht?



  • Das liegt wohl daran, dass du die cpp-Datei inkludierst. Zumindest liest es sich so, als wenn du folgendes getan hättest:

    #include "siebenSegment.hpp"
    #include "siebenSegment.cpp" /* Wenn du diese Zeile hast: weg damit */
    

    Die .o Dateien werden durch das Kompilieren erzeugt. Die musst du auf jedenfall nicht mit einbinden per include, zu einem Programm (oder was auch immer) macht das anschließend der Linker.



  • n'abend!

    Ja, das hatte ich, hab ich aber mittlerweilen auch wieder gelöscht. Nun, jetzt hab ich aber wieder das Problem der 'undefined reference', wenn ich ein Objekt der Klasse siebenSegment anlegen möchte.

    // File main.cpp
    #include "..\UebW4_Aufgabe3\siebenSegment.hpp"
    
    #include <iostream>
    using namespace std;
    
    int main(){
    	cout << "Hello World!" << endl;
    	siebenSegment::siebenSegment s; // funzt ned
    	siebenSegment a;   // funzt ebenfalls ned
    }
    

    Habe in meinem Projekt momentan nur noch das main.cpp-File, den Rest hab ich mal gelöscht. (kann ich schnell wieder basteln!=))
    Möchte zuerst sicherstellen, dass dies auch funzt.

    Nun, vielleicht seh ichs einfach nicht mehr & sollte es morgen nochmals angehen. Trotzdem wäre ich froh, wenn du's mir erklären könntest?



  • Außer das du die .hpp Datei auch dem Projekt hinzufügen musst, fällt mir so spontan au nix ein.



  • Also muss die Header-Datei im selben Ordner sein, wie das aktuelle Projekt? Ich gebe dem Compiler mit der Pfadangabe doch an, wo sich das ganze befindet?

    Weil sonst müsste ich doch auch gleich die .cpp-Datei hinzufügen, sonst weiss er ja nicht, wo er die Klassendefinition suchen soll?



  • Naja, wenn alles in der Headerdatei steht ist das kein Problem, dann nimmt sich der Compiler die Headerdatei daher und kompiliert diese. Wenn du aber Klassendefinition und Methodendefinition auf .h und .cpp aufgeteilt hast, musst du die Dateien in den Projektbaum in Eclpise mit aufnehmen (nicht in das aktuelle Verzeichnis, sondern einfach ne vorhandene Datei hinzufügen auswählen und dann die Datei aus dem entsprechenden Ordner auswählen).
    Habe das eben mal getestet mit VC++ und da bekomme ich, wenn ich die .cpp und die .h nicht ins Projekt aufnehme, diese Fehlermeldung vom Linker: "Verweis auf nicht aufgelöstes externes Symbol"

    Du könntest natürlich auch erst eine statische Bibliothek erzeugen, dann die Headerdatei dazu includen und die Bibliothek als Abhängigkeit angeben, dann sollte es auch funktionieren.

    Am Besten suchst du dir mal ein gutes Tutorial zu Eclipse raus und wie man damit C++ Projekte erstellt. Da ich deine bisherigen Einstellungen nicht kenne und sehr selten mit Eclipse arbeite, kann ich dazu nicht mehr sagen.



  • JESUS, ich mach hier jetzt dann die Schraube!
    Krieg das ganze einfach nicht hin!! =(( Kann doch nicht so schwierig sein?

    Hab jetzt folgendes gemacht:
    - die Dateien siebenSegment.cpp und ~.hpp ins neue Projekt kopiert
    - dort die Pfade in den #include-Anweisungen geändert, sprich "#include "siebenSegment.cpp" und "siebenSegment.hpp"

    Dann hab ich versucht zu kompilieren, wobei immer wieder der Fehler kam, dass ich die einzelnen Methoden mehrfach definiert hätte?!
    Im Projekt siebenSegment funzt aber alles wunderbar.

    Nun, dann hab ich mir gedacht, dass es wohl daran liegen könnte, weil im siebenSegment Projekt denselben Namen verwende, also hab ich die Dateien umbenannt, nach siebenSegment2.cpp und siebenSegment2.hpp. Da hab ich dann die include-Wächter auch angepasst, also

    #ifndef SIEBENSEGMENT2_HPP_
    #define SIEBENSEGMENT2_HPP_
    ...
    #endif /*SIEBENSEGMENT2_HPP_*/
    

    Dies hat aber auch nichts gebracht und ich zweifle wirklich langsam an mir, ob ich so doof bin oder ob sonst was nicht stimmt mit meinem Eclipse?

    Die Fehlermeldungen sind wie folgt:

    ./siebenSegment2.o: In function _ZN13siebenSegmentC2Ev': /cygdrive/c/Documents and Settings/Administrator/Eclipse/c++/UebW5_Aufgabe3/Debug/../siebenSegment2.cpp:14: multiple definition ofsiebenSegment::siebenSegment()'
    ./main.o:/cygdrive/c/Documents and Settings/Administrator/Eclipse/c++/UebW5_Aufgabe3/Debug/../siebenSegment2.cpp:14: first defined here
    ./siebenSegment2.o: In function _ZN13siebenSegmentC1Ev': /cygdrive/c/Documents and Settings/Administrator/Eclipse/c++/UebW5_Aufgabe3/Debug/../siebenSegment2.cpp:14: multiple definition ofsiebenSegment::siebenSegment()'
    ./main.o:/cygdrive/c/Documents and Settings/Administrator/Eclipse/c++/UebW5_Aufgabe3/Debug/../siebenSegment2.cpp:14: first defined here
    ./siebenSegment2.o: In function _ZN13siebenSegment12getDigitLineEii': /cygdrive/c/Documents and Settings/Administrator/Eclipse/c++/UebW5_Aufgabe3/Debug/../siebenSegment2.cpp:22: multiple definition ofsiebenSegment::getDigitLine(int, int)'
    ./main.o:/cygdrive/c/Documents and Settings/Administrator/Eclipse/c++/UebW5_Aufgabe3/Debug/../siebenSegment2.cpp:22: first defined here

    Was mache ich falsch? 😕

    Danke für die Hilfe!



  • Wie oft denn noch? Die CPP-Datei sollst du NICHT per #include dort reinpacken. Da reicht es völlig, wenn dein Linker die daraus erzeugte .O Datei in die Hände bkommt.

    Der Compiler erzeugt aus jeder CPP eine eigene .O, die alle definierten Funktionen enthält. Und durch deine Konstellation hast du die Methoden der Anzeigeklasse doppelt (einmal in der siebenSegment.o und einmal in der main.o) - das mag der Linker nicht besonders (weil er nicht zuordnen kann, welche dieser Versionen die richtige ist).



  • sorry, hab' inem andern forum gelesen, dass man das so machen soll. hab dann alles mal ausprobiert aber wollte nie klappen (logischerweise).
    Hab nochmals von vorne begonnen und jetzt gehts!

    Danke für die Geduld und die Mühe!

    mfg


Anmelden zum Antworten