Partage
  • Partager sur Facebook
  • Partager sur Twitter

Refus de compilation avec une classe template

undefined reference to 'NomDeLaClasse<type>::NomDeLaClasse(type, ...)'

Sujet résolu
    31 juillet 2023 à 10:21:44

    Bonjour

    Je dispose du code suivant qui crée comme objet un rectangle dans un écran sur lequel on peut agir sur ses attribut comme calculer son périmètre par exemple avec, ou soit des double ou des int grâce à une classe template: 

    #include <iostream>
    using namespace std;
    
    template <typename T>
    class Rectangle{
    public:
        //Le constructeur
        Rectangle(T gauche, T droite, T haut, T bas)
            :m_gauche(gauche),
             m_droite(droite),
             m_haut(haut),
             m_bas(bas)
       {}
    
        T hauteur() const
        {
          return m_haut-m_bas;
        }
    
        bool estContenu(T x, T y) const
        {
          return (x >= m_gauche) && (x <= m_droite) && (y >= m_bas) && (y <= m_haut);
        }
    
        void deplacer(T deplaceGauche, T deplaceDroite, T deplaceHaut, T deplaceBas)
        {
        m_gauche += deplaceGauche;
        m_droite += deplaceDroite;
        m_haut += deplaceHaut;
        m_bas += deplaceBas;
        // La méthode ne renvoie pas de valeur spécifique, car elle est de type void (T est le type du template)
        }
    
        T surface() const
        {
            return (m_droite-m_gauche)*(m_haut-m_bas);
        }
    
        T perimetre() const
        {
            return 2*((m_droite-m_gauche)+(m_haut-m_bas));
        }
    
    private:
    
        //Les côtés du Rectangle
        T m_gauche;
        T m_droite;
        T m_haut;
        T m_bas;
    };
    int main()
    {
        Rectangle<double> monRectangle(4.0, 8, 8, 4);
    
        cout << "La hauteur du rectangle vaut : " << monRectangle.hauteur() << endl;
        cout << "On deplace le rectangle " << endl;
        monRectangle.deplacer(-4, 0, 0, -4);
        cout << "La hauteur du rectangle vaut : " << monRectangle.hauteur() << endl;
        cout << "La surface du rectangle est : " << monRectangle.surface() << endl;
        cout << "Le perimetre du rectangle est : " << monRectangle.perimetre() << endl;
    
        return 0;
    }

    J'ai essayer de le séparer dans des fichiers .h et .cpp comme ceci :

    fichier main :

    #include <iostream>
    #include "rectangle.h"
    
    int main()
    {
        Rectangle<double> monRectangle(4.0, 8, 8, 4);
    
        std::cout << "La hauteur du rectangle vaut : " << monRectangle.hauteur() << std::endl;
        std::cout << "On deplace le rectangle " << std::endl;
        monRectangle.deplacer(-4, 0, 0, -4);
        std::cout << "La hauteur du rectangle vaut : " << monRectangle.hauteur() << std::endl;
        std::cout << "La surface du rectangle est : " << monRectangle.surface() << std::endl;
        std::cout << "Le perimetre du rectangle est : " << monRectangle.perimetre() << std::endl;
    
        return 0;
    }

    fichier .cpp :

    #include "rectangle.h"
    
    template <typename T>
    Rectangle<T>::Rectangle(T gauche, T droite, T haut, T bas)
        : m_gauche(gauche),
          m_droite(droite),
          m_haut(haut),
          m_bas(bas)
    {
    }
    
    template <typename T>
    T Rectangle<T>::hauteur() const
    {
        return m_haut - m_bas;
    }
    
    template <typename T>
    bool Rectangle<T>::estContenu(T x, T y) const
    {
        return (x >= m_gauche) && (x <= m_droite) && (y >= m_bas) && (y <= m_haut);
    }
    
    template <typename T>
    void Rectangle<T>::deplacer(T deplaceGauche, T deplaceDroite, T deplaceHaut, T deplaceBas)
    {
        m_gauche += deplaceGauche;
        m_droite += deplaceDroite;
        m_haut += deplaceHaut;
        m_bas += deplaceBas;
    }
    
    template <typename T>
    T Rectangle<T>::surface() const
    {
        return (m_droite - m_gauche) * (m_haut - m_bas);
    }
    
    template <typename T>
    T Rectangle<T>::perimetre() const
    {
        return 2 * ((m_droite - m_gauche) + (m_haut - m_bas));
    }
    

    fichier .h :

    #ifndef RECTANGLE_H_INCLUDED
    #define RECTANGLE_H_INCLUDED
    
    template <typename T>
    class Rectangle {
    public:
        Rectangle(T gauche, T droite, T haut, T bas);
        T hauteur() const;
        bool estContenu(T x, T y) const;
        void deplacer(T deplaceGauche, T deplaceDroite, T deplaceHaut, T deplaceBas);
        T surface() const;
        T perimetre() const;
    
    private:
        T m_gauche;
        T m_droite;
        T m_haut;
        T m_bas;
    };
    
    #endif // RECTANGLE_H_INCLUDED

    Le problème est qu'à chaque fois que je tente de compiler, j'ai une erreur dans le fichier main à la ligne "Rectangle<double> monRectangle(4.0, 8, 8, 4);" qui me dit ce qui est sur l'image suivante : 

    Quelqu'un arrive-t-il à interpréter cette erreur ?

    Cordialement

    -
    Edité par 1Stark 29 septembre 2023 à 18:46:19

    • Partager sur Facebook
    • Partager sur Twitter
      31 juillet 2023 à 11:12:55

      On ne met pas les implémentations de classe template dans les fichiers cpp
      • Partager sur Facebook
      • Partager sur Twitter
      ...
        31 juillet 2023 à 11:51:12

        Dois-je directement les implémenter dans le .h puis inclure ce dernier dans le main ? 

        Cordialement

        • Partager sur Facebook
        • Partager sur Twitter
          31 juillet 2023 à 12:18:19

          Oui.

          Il y a aussi la solution de mettre l'implémentation dans un fichier à part (avec l'extension tpp par exemple) et d'en faire un include après la déclaration de la classe template dans le fichier entête. 

          -
          Edité par rouIoude 31 juillet 2023 à 17:11:05

          • Partager sur Facebook
          • Partager sur Twitter
          ...

          Refus de compilation avec une classe template

          × 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