ganz schlimmer fehler!!!



  • Da exigoner sein Template auf zwei Dateien aufspalten will, muss die .cpp irgendwo eingebunden werden. Bei einem Template findet die Headerdatei "ihre" Implementierung nicht von allein.



  • GV schrieb:

    Da exigoner sein Template auf zwei Dateien aufspalten will, muss die .cpp irgendwo eingebunden werden. Bei einem Template findet die Headerdatei "ihre" Implementierung nicht von allein.

    Dazu hat Dali auf der ersten Seite bereits die Lösung gepostet. Das aktuelle Problem des OP hat damit nichts zu tun.



    1. Deklaration: template <typname T>
      const T& irgendwas (const T&, const T&);
    2. Definition:
      template <typname T>
      inline const T& irgendwas (const T& a, const T& b)
      {
      a = a+b;
      return a;
      }
    3. Implementierung:
      - Deklaration und Definition in jedem Quelltext, wo das Template
      verwendet wird
      - Falls Deklaration in separater Headerdatei und die Definition
      in einer Extra-Implementierungsdatei erfolgen, muss der Be-
      zeichner export für die Definition verwendet werden

    Eine sichere Methode ist aber, die Template-Deklaration und -Def.
    in eine Headerdatei zu schreiben und mit #ifndef vor mehrmaligen
    Einbinden zu schützen.



  • mein compiler ist beim letzten versuch abgestürzt 😞
    ich poste jetzt einfach mal wie aussieht(im mom.) und ihr wie es eurer meinung nach aussehen muss. außerdem ist jetzt noch ein guter zeitpunkt zu sagen (@linux) ich hab noch NIE mit export gearbeitet. 🤡

    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif
    
    #include <iostream>
    #include <cstdlib>
    #include "matrix.cpp"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
      int a[] = {1,2,3,4,5,6,7,8,9,8,7,6,5,4,3};
    
      matrix<int> mat(15);
      mat.setze_in_matrix(a, 15);
      mat.ausgabe_matrix();
    
      return EXIT_SUCCESS;
    }
    
    #include <iostream>
    #include <cstdlib>
    
    using namespace std;
    
    template <class T>
    class matrix
    {
    	public:
    		matrix(unsigned int z); //eine dimension
    		matrix(unsigned int z, unsigned int s);  //zwei dimemsionen
    		//matrix(int, int, int);  //noch nicht
    		~matrix();
    
    		void ausgabe_matrix();
    
    		void setze_in_matrix(T *feld); //schiebt hinten rein(matrix)
    		void setze_in_matrix(T *feld, int pos_z);  //für eindim array
    		void setze_in_matrix(T *feld, int pos_z, int pos_s); //für zweidim matrix
    
    		void fuege_array_ein(T *array);
    
    	private:
    		T *matrix_eindim;
    		T **matrix_zweidim;
    		//T ***matrix_dreidim;
    
    		unsigned int zeilen_matr;
    		unsigned int spalten_matr;
    
    		unsigned int index_z_eindim;  //damit verwechlungen ausgeschlossen sind
    		unsigned int index_z_zweidim;
    		unsigned int index_s_zweidim;
    };
    #include "matrix.cpp"
    

    (ich glaub übrigens nicht das die umbenennung zu *.inl nötig ist...

    #include <iostream>
    #include <cstdlib>
    #include "matrix.h"
    
    using namespace std;
    
    template <class T>
    matrix<T>::matrix(unsigned int zeilen)
    {
    	matrix_eindim = new T[zeilen];
    	zeilen_matr = zeilen;
    }
    
    template <class T>
    matrix<T>::matrix(unsigned int zeilen, unsigned int spalten)
    {
    	matrix_zweidim = new T*[zeilen];
    	for(int i=0; i < zeilen; i++)
    		matrix_zweidim[i] = new T[spalten];
    	zeilen_matr = zeilen;
    	spalten_matr = spalten;
    }
    
    template <class T>
    matrix<T>::~matrix()
    {
    	delete matrix_eindim[];
    	delete matrix_zweidim[];
    	//delete matrix_dreidim;
    }
    
    template <class T>
    void matrix<T>::ausgabe_matrix()
    {
    	for(int i = 0; i < zeilen_matr; i++)
    		cout<< "Position " << i << ": " << matrix_eindim[i] << endl;
    }
    
    template <class T>
    void matrix<T>::setze_in_matrix(T *feld)
    {
    	int feld_zeilen = sizeof(feld) / sizeof(feld[0]);
    	for(; index_z_eindim < feld_zeilen; index_z_eindim++)
    		matrix_eindim[index_z_eindim] = feld[index_z_eindim];
    }
    

    ursprünglich wollt ich mit der klasse mal versuchen ein neuronales netz zu schreiben... hab zwar keine ahnung wie, aber in den sommerferien wirds schon irgendwann klappen 😃



  • betrachtet mal in der main(include sektion) das *.cpp als *.h) BITTE-
    es ist aus eurem gedächtnis gerichen-->HYPNOTISCH 😮



  • Die angesprochenen include-Guards fehlen in der Header.

    Und den namensraum oeffnet man nie in einer Headerdatei.

    mfg
    v R



  • ... was soll denn

    #include "matrix.cpp"



  • Fehlersuche:
    -leeres Projekt erstellen
    -deine Headerdatei (Definition und rudimentäre Implementierung) erstellen
    -Kompilieren
    -Header im aufrufenden Modul (!) includieren
    -Kompilieren
    -sukzessive ausarbeitten ...und immer wieder kompilieren
    -konkrete Fehlermeldung posten
    -Hilfe zur Selbsthilfe bekommen
    -usw. usw



  • also als erstes, ich hab ein bisschen den destruktor überarbeitet.

    ... was soll denn
    #include "matrix.cpp"

    nochmal, das hab ich jetzt auch geändert.

    zum wesentlichem:
    wenn ich in der main nun mein objekt erstelle:

    matrix<int> mat(15);
    

    krieg ich dieses endlosfehler:
    ich hoffe ihr könnt auch denken warum ichs kompillieren abgebrochen habe.

    from matrix.h:35,
    from matrix.cpp:3,
    ...
    matrix.h:8: error: redefinition of `class matrix<T>'
    matrix.h:8: error: previous definition of `class matrix<T>'
    In file included from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from matrix.h:35,
    from matrix.cpp:3,
    from main.cpp:7:
    matrix.h:8: error: redefinition of `class matrix<T>'
    make: *** [main.lo] Fehler 1
    *** Kompilierung abgebrochen ***
    

    wichtig ist dann erstmal, denke ich, diese zeile:

    matrix.h:8: error: redefinition of `class matrix<T>'
    

    diese zeigt auf diesen code:

    #include <iostream>
    #include <cstdlib>
    
    using namespace std;
    
    template <class T>
    class matrix
    { //das ist zeile 8
    	public:
    		matrix(unsigned int z); //eine dimension
    		matrix(unsigned int z, unsigned int s);  //zwei dimemsionen
    		//matrix(int, int, int);  //noch nicht
    		~matrix();
    
    		void ausgabe_matrix();
    
    		void setze_in_matrix(T *feld); //schiebt hinten rein(matrix)
    		void setze_in_matrix(T *feld, int pos_z);  //für eindim array
    		void setze_in_matrix(T *feld, int pos_z, int pos_s); //für zweidim matrix
    
    		void fuege_array_ein(T *array);
    
    	private:
    		T *matrix_eindim;
    		T **matrix_zweidim;
    		//T ***matrix_dreidim;
    
    		unsigned int zeilen_matr;
    		unsigned int spalten_matr;
    
    		unsigned int index_z_eindim;  //damit verwechlungen ausgeschlossen sind
    		unsigned int index_z_zweidim;
    		unsigned int index_s_zweidim;
    };
    #include "matrix.cpp"
    

    so, helft mir, mir selbst zu helfen... codeschnipsel erwünscht 💡



  • Sry, aber schreib ich etwa chinesich?

    mfg
    v R



  • halt noch ne überarbeitung, er fehler kommt nicht wenn ichs objekt erstelle, sondern wenn ich unter der klasse die matrix.cpp includieere.

    wenn ich das include weglasse kommt wieder der gewohnte fehler:

    main.cpp:(.text+0x2c): undefined reference to `matrix<int>::setze_in_matrix(int*, int)'
    collect2: ld returned 1 exit status
    make[2]: *** [anne] Fehler 1
    

    trotzdem, wer nun weiß wie man das fehlerfrei kompilliertt finger HOCH. ich denke man kann den code leicht per copy and paste übernehmen und testen, ich hab es ja nicht umsonst hier ins forum gestellt...



  • achso, sry virtual,
    ich kann mir denken was include guards sind, aber wie muss ich die machen?????



  • exigoner schrieb:

    achso, sry virtual,
    ich kann mir denken was include guards sind, aber wie muss ich die machen?????

    Deine Header muss so aussehen:

    #ifndef headernameH
    #define headernameH
    
    //jede menge code
    
    #include "matrix.cpp"
    
    #endif
    

    Dein Problem war bis jetzt, dass du eine endlos Includierung erzeugt hast, denn

    1. matrix.h includiert matrix.cpp
    2. matrix.cpp includiert matrix.h
    3. ... usw. usf.

    Der Includeguard sagt:

    headernameH schon definiert? Wenn nicht, dann definiere ihn und liess den Rest
    ein, ansonsten ignoriere den Rest.

    mfg
    v R



  • ok, ich hab jetzt meine includeguards gesetzt...



  • matrix.cpp:11: error: expected constructor, destructor, or type conversion before '<' token
    matrix.cpp:11: error: expected `;' before '<' token
    matrix.cpp:19: error: expected constructor, destructor, or type conversion before '<' token
    matrix.cpp:19: error: expected `;' before '<' token
    matrix.cpp:29: error: expected constructor, destructor, or type conversion before '<' token
    matrix.cpp:29: error: expected `;' before '<' token
    matrix.cpp:37: error: expected init-declarator before '<' token
    matrix.cpp:37: error: expected `;' before '<' token
    matrix.cpp:44: error: expected init-declarator before '<' token
    matrix.cpp:44: error: expected `;' before '<' token
    


  • wenn ich jetzt die includeguards in der matrix.CPP weglasse, kommt aber das hier:

    matrix.cpp:9: error: redefinition of `matrix<T>::matrix(unsigned int)'
    matrix.cpp:9: error: `matrix<T>::matrix(unsigned int)' previously declared here
    matrix.cpp:16: error: redefinition of `matrix<T>::matrix(unsigned int, unsigned int)'
    matrix.cpp:16: error: `matrix<T>::matrix(unsigned int, unsigned int)' previously declared here
    matrix.cpp:26: error: redefinition of `matrix<T>::~matrix()'
    matrix.cpp:26: error: `matrix<T>::~matrix()' previously declared here
    matrix.cpp:34: error: redefinition of `void matrix<T>::ausgabe_matrix()'
    matrix.cpp:34: error: `void matrix<T>::ausgabe_matrix()' previously declared here
    matrix.cpp:41: error: redefinition of `void matrix<T>::setze_in_matrix(T*)'
    matrix.cpp:41: error: `void matrix<T>::setze_in_matrix(T*)' previously declared here
    


  • Die Includeguards kommen in die Headerdatei. Und in der .cpp-Datei brauchst du
    die .h-Datei nicht mehr includieren. Nach der include-Zeile in der Header steht
    der Code ja quasi direkt untereinander.

    Auch hier ist es besser, den Namensraum nicht zu oeffnen und auch in der
    .cpp-Datei mit dem std::-Prefix zu arbeiten.

    mfg
    v R



  • ok;
    meine klasse sieht dann so aus:

    #ifndef matrix_klasse
    #define matrix_klasse
    
    #include <iostream>
    #include <cstdlib>
    
    using namespace std;
    
    template <class T>
    class matrix
    {
    	public:
    		matrix(unsigned int z); //eine dimension
    		matrix(unsigned int z, unsigned int s);  //zwei dimemsionen
    		//matrix(int, int, int);  //noch nicht
    		~matrix();
    
    		void ausgabe_matrix();
    
    		void setze_in_matrix(T *feld); //schiebt hinten rein(matrix)
    		void setze_in_matrix(T *feld, int pos_z);  //für eindim array
    		void setze_in_matrix(T *feld, int pos_z, int pos_s); //für zweidim matrix
    
    		void fuege_array_ein(T *array);
    
    	private:
    		T *matrix_eindim;
    		T **matrix_zweidim;
    		//T ***matrix_dreidim;
    
    		unsigned int zeilen_matr;
    		unsigned int spalten_matr;
    
    		unsigned int index_z_eindim;  //damit verwechlungen ausgeschlossen sind
    		unsigned int index_z_zweidim;
    		unsigned int index_s_zweidim;
    };
    #include "matrix.cpp"
    
    #endif
    
    #include <iostream>
    #include <cstdlib>
    
    template <class T>
    matrix<T>::matrix(unsigned int zeilen)
    {
    	matrix_eindim = new T[zeilen];
    	zeilen_matr = zeilen;
    }
    
    template <class T>
    matrix<T>::matrix(unsigned int zeilen, unsigned int spalten)
    {
    	matrix_zweidim = new T*[zeilen];
    	for(int i=0; i < zeilen; i++)
    		matrix_zweidim[i] = new T[spalten];
    	zeilen_matr = zeilen;
    	spalten_matr = spalten;
    }
    
    template <class T>
    matrix<T>::~matrix()
    {
    	delete [] matrix_eindim;
    	delete [] matrix_zweidim;
    	//delete matrix_dreidim;
    }
    
    template <class T>
    void matrix<T>::ausgabe_matrix()
    {
    	for(int i = 0; i < zeilen_matr; i++)
    		cout<< "Position " << i << ": " << matrix_eindim[i] << endl;
    }
    
    template <class T>
    void matrix<T>::setze_in_matrix(T *feld)
    {
    	int feld_zeilen = sizeof(feld) / sizeof(feld[0]);
    	for(; index_z_eindim < feld_zeilen; index_z_eindim++)
    		matrix_eindim[index_z_eindim] = feld[index_z_eindim];
    }
    
    matrix.cpp:5: error: expected constructor, destructor, or type conversion before '<' token
    matrix.cpp:5: error: expected `;' before '<' token
    matrix.cpp:12: error: expected constructor, destructor, or type conversion before '<' token
    matrix.cpp:12: error: expected `;' before '<' token
    matrix.cpp:22: error: expected constructor, destructor, or type conversion before '<' token
    matrix.cpp:22: error: expected `;' before '<' token
    matrix.cpp:30: error: expected init-declarator before '<' token
    matrix.cpp:30: error: expected `;' before '<' token
    matrix.cpp:37: error: expected init-declarator before '<' token
    matrix.cpp:37: error: expected `;' before '<' token
    

    mir scheint an erfahrung zu mangeln...



  • @exigoner:
    Dein Hauptprogramm sollte so aussehen:

    #include "matrix.hpp"
    
    int main()
    {
          return 0;
    }
    

    Beachte das du in dein Hauptmodul den header matrix.hpp einbinden musst und nicht die matrix.cpp...

    Caipi



  • also meine main:

    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif
    
    #include <iostream>
    #include <cstdlib>
    #include "matrix.h"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
      int a[] = {1,2,3,4,5,6,7,8,9,8,7,6,5,4,3};
    
      matrix<int> mat(15);
      mat.setze_in_matrix(a, 15);
      mat.ausgabe_matrix();
    
      return EXIT_SUCCESS;
    }
    

    sieht ganz gut aus... außerdem hab ich meine klasse ganz normal matrix.h und meine getrennte implementation matrix.cpp genannt. (siehe oben)
    der fehler liegt damit best. wieder in dieser beschissenen klasse. 😞
    [heul]


Anmelden zum Antworten