IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Classe template / méthode static


Sujet :

Langage C++

  1. #1
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Mai 2007
    Messages
    123
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2007
    Messages : 123
    Par défaut Classe template / méthode static
    Bonjour, je développe une classe template qui contient, entre autre, une méthode statique, le tout implémenté de la façon suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    template <typename T>
    class Vec3
    {
    private:
        T m_values[3];
     
    public:
        Vec3(const T& _value1 = T(), const T& _value2 = T(), const T& _value3 = T());
        Vec3(const Vec3<T>& _vector);
        ~Vec3();
     
        T x() { return m_values[0]; }
        T y() { return m_values[1]; }
        T z() { return m_values[2]; }
     
        void setX(T _value) { m_values[0] = _value; }
        void setY(T _value) { m_values[1] = _value; }
        void setZ(T _value) { m_values[2] = _value; }
        void set(Vec3<T> _vector) { setX(_vector.x()); setY(_vector.y()); setZ(_vector.z()); }
     
        T* toArray() { return m_values; }
     
        static double distance(const Vec3<T>& _vec1, const Vec3<T>& _vec2);
        static double dotProduct(const Vec3<T>& _vec1, const Vec3<T>& _vec2);
        static Vec3<T> crossProduct(const Vec3<T>& _vec1, const Vec3<T>& _vec2);
    };
     
    // CONSTRUCTEURS
    template <typename T>
    Vec3<T>::Vec3(const T& _value1, const T& _value2, const T& _value3)
    {
        setX(_value1);
        setY(_value2);
        setZ(_value3);
    }
     
    template <typename T>
    Vec3<T>::Vec3(const Vec3<T>& _vector)
    {
        set(_vector);
    }
     
    // DESTRUCTEUR
    template <typename T>
    Vec3<T>::~Vec3()
    {
        delete [] m_values;
    }
     
    // DISTANCE
    template <typename T>
    double distance(const Vec3<T>& _vec1, const Vec3<T>& _vec2)
    {
        return (sqrt(pow(_vec2.x() - _vec1.x(), 2)) + pow(_vec2.y() - _vec1.y(), 2) + pow(_vec2.z() - _vec1.z(), 2));
    }
     
    // PRODUIT SCALAIRE
    template <typename T>
    double dotProduct(const Vec3<T>& _vec1, const Vec3<T>& _vec2)
    {
        return (_vec1.x * _vec2.x + _vec1.y * _vec2.y + _vec1.z * _vec2.z);
    }
     
    // PRODUIT VECTORIEL
    template <typename T>
    Vec3<T> crossProduct(const Vec3<T>& _vec1, const Vec3<T>& _vec2)
    {
        Vec3<T> vector;
        vector.setX((_vec1.y * _vec2.z) - (_vec1.z * _vec2.y));
        vector.setY((_vec1.z * _vec2.x) - (_vec1.x * _vec2.z));
        vector.setZ((_vec1.x * _vec2.y) - (_vec1.y * _vec2.x));
        return vector;
    }
     
     
    typedef Vec3<int> Vec3i;
    typedef Vec3<float> Vec3f;
    typedef Vec3<double> Vec3d;
    typedef Vec3<unsigned char> Vec3uc;
    Et dans mon main, je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Vec3d vec1 = Vec3d(3.0, 3.0, 3.0);
    Vec3d vec2 = Vec3d(1.0, 1.0, 1.0);
     
    cout<<Vec3d::distance(vec1, vec2)<<endl;
    Et ça me renvoie cette erreur :
    "undefined reference to 'Vec3<double>::distance(Vec3<double> const&, Vec3<double> const&)'"

    Pourtant l'implémentation est bien là donc je ne comprends pas le souci.

    Ah, et j'ai une petite question sans rapport mais si j'avais mis T x, T y, T z à la place d'un tableau de 3 T, comment est-ce que j'aurais pu faire pour renvoyer un tableau à partir de la méthode toArray() ? Si je crée un tableau à partir des 3 variables dans la méthode et que je le retourne, ça fonctionne bizarrement selon le compilateur vu que c'est un un tableau local à la méthode.

  2. #2
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    1/ distance appartient a Vec3 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template <typename T>
    double Vec3<T>::distance(const Vec3<T>& _vec1, const Vec3<T>& _vec2)
    {
        return (sqrt(pow(_vec2.x() - _vec1.x(), 2)) + pow(_vec2.y() - _vec1.y(), 2) + pow(_vec2.z() - _vec1.z(), 2));
    }
    2/ distance devrait etre une fonction libre et pas un truc static

    3/ Pour renvoeyr un tableau, renvoti un boost::array<T,3> qui a une semantique du premier ordre contrairement a T[3]

  3. #3
    Membre confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2010
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 80
    Par défaut
    en plus de joel F :

    les méthodes x(), y(), et z() doivent être const

    les pow(x, 2), il vaut mieux éviter, ça prend un peu trop de temps par rapport à une simple multiplication...

    sur ton destructeur, il faut caster ton m_values en T* pour éviter un warning de destruction de type incomplet.

  4. #4
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Citation Envoyé par regis.portalez Voir le message
    en plus de joel F :

    les méthodes x(), y(), et z() doivent être const

    les pow(x, 2), il vaut mieux éviter, ça prend un peu trop de temps par rapport à une simple multiplication...

    sur ton destructeur, il faut caster ton m_values en T* pour éviter un warning de destruction de type incomplet.

    ?

    C'est surtout qu'il faut pas delete du tout... c'est un tableau statique.

  5. #5
    Membre confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2010
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 80
    Par défaut


    Ah ben oui en effet...

  6. #6
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Mai 2007
    Messages
    123
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2007
    Messages : 123
    Par défaut
    Bonjour et merci de vos réponses.

    Si je rends la méthode distance libre (ce qui serait le plus logique, je le concède), j'ai d'autres erreurs de type :
    no type named 'iterator_category' in 'class Vec3<double>'
    no type named 'value_type' in 'class Vec3<double'
    no type named 'difference_type' in 'class Vec3<double>'
    etc...
    dans stl_iterator_base_types.h ....

    Ok pour les const et les pow par contre j'ai pas saisi le problème sur le destructeur.

  7. #7
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Citation Envoyé par Daikyo Voir le message
    Bonjour et merci de vos réponses.

    Si je rends la méthode distance libre (ce qui serait le plus logique, je le concède), j'ai d'autres erreurs de type :
    no type named 'iterator_category' in 'class Vec3<double>'
    no type named 'value_type' in 'class Vec3<double'
    no type named 'difference_type' in 'class Vec3<double>'
    etc...
    dans stl_iterator_base_types.h ....

    Ok pour les const et les pow par contre j'ai pas saisi le problème sur le destructeur.

    Tu appelles delete [] sur un tableau alloué sur la pile... (tu fais jamais de new*[]).

    Pour le reste, t'as pas de stl dans le code que tu nous montres et là t'as des erreurs dans les header de la STL.

  8. #8
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Mai 2007
    Messages
    123
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2007
    Messages : 123
    Par défaut
    C'est justement là le souci, c'est que je vous ai tout montré !

    Vec3.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
     
    #ifndef VEC3_H
    #define VEC3_H
     
    #include <math.h>
     
    template <typename T>
    class Vec3
    {
    private:
        T m_values[3];
     
    public:
        Vec3(const T& _value1 = T(), const T& _value2 = T(), const T& _value3 = T());
        Vec3(const Vec3<T>& _vector);
        ~Vec3();
     
        T x() { return m_values[0]; }
        T y() { return m_values[1]; }
        T z() { return m_values[2]; }
     
        void setX(T _value) { m_values[0] = _value; }
        void setY(T _value) { m_values[1] = _value; }
        void setZ(T _value) { m_values[2] = _value; }
        void set(Vec3<T> _vector) { setX(_vector.x()); setY(_vector.y()); setZ(_vector.z()); }
     
        T* toArray() { return m_values; }
     
        //static double distance(const Vec3<T>& _vec1, const Vec3<T>& _vec2);
        //static double dotProduct(const Vec3<T>& _vec1, const Vec3<T>& _vec2);
        //static Vec3<T> crossProduct(const Vec3<T>& _vec1, const Vec3<T>& _vec2);
    };
     
    // CONSTRUCTEURS
    template <typename T>
    Vec3<T>::Vec3(const T& _value1, const T& _value2, const T& _value3)
    {
        setX(_value1);
        setY(_value2);
        setZ(_value3);
    }
     
    template <typename T>
    Vec3<T>::Vec3(const Vec3<T>& _vector)
    {
        set(_vector);
    }
     
    // DESTRUCTEUR
    template <typename T>
    Vec3<T>::~Vec3()
    {
    }
     
    // DISTANCE
    template <typename T>
    double distance(const Vec3<T>& _vec1, const Vec3<T>& _vec2)
    {
        return (sqrt(pow(_vec2.x() - _vec1.x(), 2)) + pow(_vec2.y() - _vec1.y(), 2) + pow(_vec2.z() - _vec1.z(), 2));
    }
     
    // PRODUIT SCALAIRE
    template <typename T>
    double dotProduct(const Vec3<T>& _vec1, const Vec3<T>& _vec2)
    {
        return (_vec1.x * _vec2.x + _vec1.y * _vec2.y + _vec1.z * _vec2.z);
    }
     
    // PRODUIT VECTORIEL
    template <typename T>
    Vec3<T> crossProduct(const Vec3<T>& _vec1, const Vec3<T>& _vec2)
    {
        Vec3<T> vector;
        vector.setX((_vec1.y * _vec2.z) - (_vec1.z * _vec2.y));
        vector.setY((_vec1.z * _vec2.x) - (_vec1.x * _vec2.z));
        vector.setZ((_vec1.x * _vec2.y) - (_vec1.y * _vec2.x));
        return vector;
    }
     
     
    typedef Vec3<int> Vec3i;
    typedef Vec3<float> Vec3f;
    typedef Vec3<double> Vec3d;
    typedef Vec3<unsigned char> Vec3uc;
     
    #endif // VEC3_H
    main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #include <stdlib.h>
    #include <iostream>
     
    #include "Vec3.h"
     
    using namespace std;
     
    int main()
    {
        Vec3d vec1 = Vec3d(3.0, 3.0, 3.0);
        Vec3d vec2 = Vec3d(1.0, 1.0, 1.0);
     
        cout<<distance(vec1, vec2)<<endl;
     
        system("PAUSE");
        return 0;
    }

  9. #9
    Membre confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2010
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 80
    Par défaut
    je viens de tester le code et si tu enlèves le "using namespace std", les erreurs disparaissent.


    enlève le "using namespace std" et utilise le explicitement (std::cout, std::endl, ...) ou mets ta classe et tes fonctions dans un autre namespace.

  10. #10
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Mai 2007
    Messages
    123
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2007
    Messages : 123
    Par défaut
    Oki merci beaucoup, problem solved

  11. #11
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Parce que distance est un algorithme de la STL.
    http://www.sgi.com/tech/stl/distance.html

    c'est pour ça que les namespace c'est bien.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Définition de méthodes pour une classe template
    Par Pragmateek dans le forum Langage
    Réponses: 13
    Dernier message: 20/12/2008, 00h46
  2. Réponses: 9
    Dernier message: 12/04/2007, 17h08
  3. classe Template et méthodes "générales"
    Par rulianf dans le forum Langage
    Réponses: 1
    Dernier message: 26/10/2005, 13h42
  4. Réponses: 6
    Dernier message: 27/07/2005, 09h06
  5. [FLASH MX2004] [AS2] Classe méthodes static
    Par bolo dans le forum ActionScript 1 & ActionScript 2
    Réponses: 2
    Dernier message: 16/12/2004, 18h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo