Partage
  • Partager sur Facebook
  • Partager sur Twitter

Erreur récalcitrante "undefined reference to"

En rapport avec l'utilisation de templates

Sujet résolu
    6 avril 2008 à 20:29:01

    lates avec lesquels je ne suis pas très à l'aise... Peut-être est-ce une erreur de débutant, en tout cas je vous serais reconnaissant si vous pouviez m'indiquer comment corriger cette erreur !
    D'avance merci !onne. Voici mes classes :

    Classe CMatrix (CMatrix.h)
    1. #ifndef MATRIX_H
    2.    #define MATRIX_H
    3.    #include <iostream>
    4.    using namespace std;
    5.    template <class type>
    6.    class CMatrix
    7.    {
    8.       protected:
    9.       unsigned int
    10.          height,
    11.          width;
    12.       type* table;
    13.       public:
    14.       CMatrix<type>() : height(0), width(0), table(NULL) {};
    15.       CMatrix<type>(const CMatrix<type>*);
    16.       CMatrix<type>(const unsigned int, const unsigned int, const type* newTable = NULL);
    17.       ~CMatrix<type>();
    18.       void set(const unsigned int, const unsigned int, const type* newTable = NULL);
    19.       void set(const unsigned int, const unsigned int, const type);
    20.       void reset();
    21.       unsigned int getHeight() const;
    22.       unsigned int getWidth() const;
    23.       friend CMatrix<type> operator+(const CMatrix<type>&, const CMatrix<type>&);
    24.       friend CMatrix<type> operator*(const CMatrix<type>&, const CMatrix<type>&);
    25.       CMatrix<type>        operator=(const CMatrix<type>&);
    26.       type                 operator()(const unsigned int, const unsigned int column = 1) const;
    27.    };
    28. /* Viennent ensuite les définitions de toutes les méthodes ci-dessus, puisque l'utilisation de templates l'impose ; j'ai coupé cette partie pour plus de lisibilité, mais n'hésitez pas à m'en demander le contenu. */


    Classe CWord (CWord.h)
    1. #ifndef CWORD_H
    2.    #define CWORD_H
    3.    #include "CMatrix.h"
    4.    class CWord
    5.    {
    6.       CMatrix<bool> word;
    7.       bool          checkSum;
    8.       unsigned int
    9.          size,
    10.          repetition,
    11.          hamming[2];
    12.       public:
    13.       CWord() : word(0, 1), checkSum(false), size(0), repetition(1) { hamming[0] = hamming[1] = 0; };
    14.       CWord(const unsigned int, const bool*);
    15.       CWord(const CMatrix<bool>);
    16.       CMatrix<bool> getMatrix() const;
    17.       bool*         getString() const;
    18.       bool          getCheckSum() const;
    19.       unsigned int  getDecimalValue() const;
    20.       bool*         extract(const unsigned int, const unsigned int) const;
    21.       void set(const unsigned int, const bool* newWord = NULL);
    22.       void set(const unsigned int, const bool);
    23.       void reset();
    24.       void setCheckSum();
    25.       bool testCheckSum();
    26.       void repeat(const unsigned short);
    27.       void unrepeat();
    28.       void encodeHamming74();
    29.       void decodeHamming74();
    30.       friend CWord operator*(const CWord&, const CWord&);
    31.       friend CWord operator*(const CMatrix<bool>&, const CWord&);
    32.       CWord  operator=(const CWord&);
    33.       double operator()(const unsigned int) const;
    34.    };
    35. #endif


    Je ne vous fournirai la déclaration que des 2 opérateurs de multiplication puisqu'ils sont à l'origine des erreurs dont je vais vous parler :

    1. //Operators
    2. CWord operator*(const CWord& word1, const CWord& word2)
    3. {
    4.    return CWord(word1.getMatrix() * word2.getMatrix());
    5. }
    6. CWord operator*(const CMatrix<bool>& matrix, const CWord& word)
    7. {
    8.    return CWord(matrix * word.getMatrix());
    9. }

    Lorsque je compile, j'obtiens les erreurs suivantes que je n'arrive pas à corriger :
    CWord.o: In function `operator*(CMatrix<bool> const&, CWord const&)':
    CWord.cpp:(.text+0xa0b): undefined reference to `operator*(CMatrix<bool> const&, CMatrix<bool> const&)'
    CWord.o: In function `operator*(CWord const&, CWord const&)':
    CWord.cpp:(.text+0xac8): undefined reference to `operator*(CMatrix<bool> const&, CMatrix<bool> const&)'
    collect2: ld a retourné 1 code d'état d'exécution
    make: *** [CorrectorCode] Erreur 1

    Je suopçonne une mauvaise utilisation des temp
    • Partager sur Facebook
    • Partager sur Twitter
      6 avril 2008 à 20:37:53

      vas voir la FAQ de developpez sur les templates, ca t'aideras (sinon j'ai pas trop regardé)
      • Partager sur Facebook
      • Partager sur Twitter
        6 avril 2008 à 20:40:33

        As-tu ajouté dans ton projet l'implémentation de CMatrix (qui j'espère n'est pas le fichier .h!)?
        • Partager sur Facebook
        • Partager sur Twitter
          6 avril 2008 à 20:48:32

          Justement oui, à cause de l'utilisation des templates je suis contraint d'implémenter la classe CMatrix dans le même fichier .h que sa déclaration ! Je vous l'ai mis en commentaire, mais afin de dissiper tous vos doutes, voici la fonction que le compilateur prétend "undefined" :

          1. template <class type>
          2.    CMatrix<type> operator*(const CMatrix<type>& matrix1, const CMatrix<type>& matrix2)
          3.    {
          4.       if (matrix1.getWidth() == matrix2.getHeight())
          5.       {
          6.          unsigned int i = 0, j = 0, k = 0;
          7.          type*      temp = new type[matrix1.getHeight() * matrix2.getWidth()];
          8.          i = 0;
          9.          while (i < matrix1.getHeight())
          10.          {
          11.             while (j < matrix2.getWidth())
          12.             {
          13.                temp[i*matrix2.getWidth() + j] = 0;
          14.                while (k < matrix1.getWidth())
          15.                {
          16.                   temp[i*matrix2.getWidth() + j] += matrix1(i, k) * matrix2(k, j);
          17.                   k++;
          18.                }
          19.                k = 0;
          20.                j++;
          21.             }
          22.             j = 0;
          23.             i++;
          24.          }
          25.          CMatrix<type> result(matrix1.getHeight(), matrix2.getWidth(), (const type*)temp);
          26.          delete[] temp;
          27.          return result;
          28.       }
          29.       return CMatrix<type>(0, 0);
          30.    }
          • Partager sur Facebook
          • Partager sur Twitter
            6 avril 2008 à 21:00:41

            il me semble que lmghs avait dit que dans le cas particulier des matrices, op*() doit etre membre, et VAS VOIR LA FAQ DE DEVELOPPEZ
            • Partager sur Facebook
            • Partager sur Twitter
              6 avril 2008 à 21:08:18

              Je vais voir ça d'un peu plus prêt, bien qu'a priori je ne comprenne pas pourquoi il y aurait nécessité d'avoir un opérateur interne...
              C'est même à mon sens moins pratique car on est alors contraint de modifier la matrice sur laquelle on opère, alors que si je veux multiplier deux matrices et étudier le résultat, je ne veux pas toucher aux matrices opérandes...

              PS : j'ai déjà lu la FAQ de développez depuis longtemps, j'ai même lu un bout cours magistral sur les templates sur developpez...

              EDIT : apparemment, la surcharge d'un opérateur externe résulte toujours sur un opérateur symétrique, ce qui n'est pas le cas pour les matrices ; il faut donc bien utiliser un opérateur interne... Je vais modifier ça et voir si l'erreur est toujours là...

              EDIT 2 : étrangement, après cette rectification, l'erreur a disparu... je dis étrangement car cela n'avait rien d'un "undefined reference" prétendu par le compilateur... L'important après tout est que ça fonctionne, donc je vous remercie !
              • Partager sur Facebook
              • Partager sur Twitter
                6 avril 2008 à 21:53:52

                Citation : Chahine

                Je vais voir ça d'un peu plus prêt, bien qu'a priori je ne comprenne pas pourquoi il y aurait nécessité d'avoir un opérateur interne...
                C'est même à mon sens moins pratique car on est alors contraint de modifier la matrice sur laquelle on opère, alors que si je veux multiplier deux matrices et étudier le résultat, je ne veux pas toucher aux matrices opérandes...


                Une opération interne va appeler a.operator*(b). En externe, c'est operator*(a,b). Dans ton cas, utiliser l'un ou l'autre revient au même.

                Citation : Chahine


                EDIT : apparemment, la surcharge d'un opérateur externe résulte toujours sur un opérateur symétrique, ce qui n'est pas le cas pour les matrices ; il faut donc bien utiliser un opérateur interne... Je vais modifier ça et voir si l'erreur est toujours là...


                Faux : ce n'est jamais symétrique. int*CMatrix != CMatrix*int.

                Citation : Chahine


                EDIT 2 L'important après tout est que ça fonctionne, donc je vous remercie !


                L'important est que tu comprennes ce que tu fais, et que tu ne refasses pas la même erreur.
                http://cpp.developpez.com/faq/cpp/?page=templates#DIVERS_templates
                Tu écris template<class type> alors que developpez.com aurait écrit template<typename type>; mais je ne sais absolument pas la différence.
                • Partager sur Facebook
                • Partager sur Twitter
                  6 avril 2008 à 22:09:14

                  Citation : Pole

                  Une opération interne va appeler a.operator*(b). En externe, c'est operator*(a,b). Dans ton cas, utiliser l'un ou l'autre revient au même.


                  D'après ce que j'ai lu sur developpez.com, sauf erreur de ma part, non justement, car un opérateur externe ne différencie pas l'ordre des opérandes :

                  Citation : developpez.com

                  [Dans le paragraphe sur les opérateurs externes]
                  L'avantage de cette syntaxe est que l'opérateur est réellement symétrique, contrairement à ce qui se passe pour les opérateurs définis à l'intérieur de la classe.



                  Je vais me renseigner sur la différence entre class et typename.
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Erreur récalcitrante "undefined reference to"

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown