Linker error: undefined reference to ...



  • Hi,
    ich versuche mich gerade an Aufgabe 7 von hier:
    http://www.cpp-entwicklung.de/cpplinux3/cpp_main/cpp_mainch2.html#x3-1290002.6.10

    Ich splitte meinen Code erst seit Kurzem in mehrere Files, diese Header etc. sind mir daher noch neu. Irgendwo da liegt wohl auch mein Linker-Fehler begraben:

    03_S93_A3_main.cpp:(.text+0x29): undefined reference to Rational::Rational()' 03\_S93\_A3_main.cpp:(.text+0x45): undefined reference toRational::set(long, long)'
    03_S93_A3_main.cpp:(.text+0x61): undefined reference to Rational::set(long, long)' 03\_S93\_A3_main.cpp:(.text+0x70): undefined reference tostd::cout'

    Das sind nur 4 Zeilen, die richtige Fehlermeldung ist ca. zehnmal so lang, mit lauter 'undefined references'.

    Hier meine Dateien:

    03_S93_A3_main.cpp

    #include <iostream>
    #include "03_S93_A3_classes.h"
    
    int main()
    {
        Rational halb, neuntel, temp;
        halb.set(3,6);
        neuntel.set(1,9);
    
        std::cout << "Halb: ";
        halb.ausgabe();
        temp.sub(halb,neuntel);
        std::cout << "halb - neuntel: ";
        temp.ausgabe();
        return 0;
    }
    

    03_S93_A3_classes.h

    class Rational
    {
    private:
    	long zaehler, nenner;
    	long ggT (long _a,long _b);
    
    public:
    	Rational();
    
    	void add(Rational& _a, Rational& _b);
    	void sub(Rational& _a, Rational& _b);
    	void mult(Rational& _a, Rational& _b);
    	void div(Rational& _a, Rational& _b);
    
    	void set(long _z, long _n);
    	void kuerzen();
    	void ausgabe();
    };
    

    03_S93_A3_classes.cpp

    #include <iostream>
    
    class Rational
    {
    private:
    	long zaehler, nenner;
    	long ggT (long _x,long _y)
    	{
    		while(_y)
    		{
    			long r = _x % _y;
    			_x = _y;
    			_y = r;
    		}
    		return (_x);
    	}
    
    public:
    	Rational(){ set(0,1); }
    
    	void add(Rational& _a, Rational& _b)
    	{
    		set( _a.zaehler * _b.nenner + _a.nenner * _b.zaehler , _a.nenner * _b.nenner );
    	}
    	void sub(Rational& _a, Rational& _b)
    	{
    		set( _a.zaehler * _b.nenner - _a.nenner * _b.zaehler , _a.nenner * _b.nenner );
    	}
    	void mult(Rational& _a, Rational& _b)
    	{
    		set( _a.zaehler * _b.zaehler , _a.nenner * _b.nenner );
    	}
    	void div(Rational& _a, Rational& _b)
    	{
    		set( _a.zaehler * _b.nenner , _a.nenner * _b.zaehler );
    	}
    
    	void set(long _z, long _n)
    	{
    		// this.zaehler ?
    		zaehler = _z;
    		nenner = _n;
    		// this.kuerzen ?
    		kuerzen();
    	}
    	void kuerzen()
    	{
    		int ggt = ggT(zaehler,nenner);
    		zaehler /= ggt;
    		nenner /= ggt;
    	}
    	void ausgabe()
    	{
    		std::cout << zaehler << "/" << nenner << std::endl;
    	}
    };
    

    Wäre super, wenn jemand findet, was ich da verbockt habe.
    Danke schon mal 🙂



  • Du sollst in der .cpp-Datei nicht die komplette Klasse neu definieren, sondern nur ihre Methoden.

    void Rational::set(long _z, long _n)
    {
        ...
    }
    


  • Hey,
    ja, in der Lösung wird das so gemacht.
    Muss kurz sagen, dass ich von C komme, und mit Objektorientierung immer noch Schwierigkeiten hab.

    Ich sehe in der Headerdatei so eine Art Prototyp einer Funktion, die man später nochmal ganz ausschreibt. Genauso hab ich das mit der Klasse gemacht.
    Was an dem Gedanken ist da falsch?

    Was ich gemacht habe, ist also keine (umständlichere) Alternative, sondern falsch. Seltsam. Aber danke 🙂



  • Du darfst Dinge nicht zwei Mal definieren (One Definition Rule). Da die Klassendefinition schon im Header vorkommt, kann und muss sie in der .cpp-Datei weggelassen werden.

    Bei den Funktionen hingegen hast du im Header nur die Deklaration (wie du sagst den Prototypen), die Definition (Implementierung) kannst du in die .cpp-Datei auslagern. In C ist das ja ähnlich.



  • Ha!
    Klassendefinition und Methodendefinition. Die hab ich blöderweise unter einen Hut gesteckt. Danke dir!



  • Gerald Ast schrieb:

    Ha!
    Klassendefinition und Methodendefinition. Die hab ich blöderweise unter einen Hut gesteckt. Danke dir!

    Klassendefinition:

    class foo
    {
       void bar();
    };
    

    Implementation:

    #include <foo.hpp>
    
    void foo::bar() 
    {
        while (1) 
        {
            ProgramDukeNukemForever(new Engine(ENGINE_VERSION_2011));
        }
    }
    

    rya.


Anmelden zum Antworten