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

C++ Discussion :

affectation de classes generiques


Sujet :

C++

  1. #1
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut affectation de classes generiques
    Bonjour tout le monde

    Soit une classe generique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template <class Telem>
    class Vecteur
    {
     
    //declaration de la classe !!
     
    }
    et j'ai deux instances
    Vecteur<int> v1;
    et
    Vecteur<float> v2;

    Comment puis-je affecter la deuxieme instance a la premiere ??
    v1=v2;

    merci de votre aide !!!

  2. #2
    jmv
    jmv est déconnecté
    Membre confirmé Avatar de jmv
    Profil pro
    Enseignant
    Inscrit en
    Mai 2004
    Messages
    395
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mai 2004
    Messages : 395
    Points : 603
    Points
    603
    Par défaut
    salut,
    Impossible de te repondre sans connaitre ta classe Vecteur.

    Avec la classe vector de la STL je ferais comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    v1.resize(v2.size());
    for(int i=0; i<v1.size(); i++)
        v1[i] = (int)v2[i];

  3. #3
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    voici ma classe :

    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
    template <class Telem=int,int N=0,Telem zero=0>
    class Vector  
    {
    public:
     
    Vector(){for(int i=0;i<N;i++){tab[i]=zero;}};
    Vector<Telem,N,zero> operator+(const Vector<Telem,N,zero> &V);
    Vector<Telem,N,zero>& operator=(const Vector<Telem,N,zero> &V);
    Telem operator[](int i);
    virtual ~Vector();
     
    private:
     
    Telem tab[N];
     
    };
    l'idée est que lors de la'affectation le cast se fait implicitement !!!

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Voir le thread " Classe Matrix<T>" où ce sujet a été discuté

  5. #5
    jmv
    jmv est déconnecté
    Membre confirmé Avatar de jmv
    Profil pro
    Enseignant
    Inscrit en
    Mai 2004
    Messages
    395
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mai 2004
    Messages : 395
    Points : 603
    Points
    603
    Par défaut
    j'adapte mon code précédement posté à ta classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    const int size=10; // par exemple
    Vecteur<int,size> v1;
    Vecteur<double,size> v2;
    ...
    for(int i=0; i<size; i++)
        v1[i] = (int)v2[i];
    (code non testé )

    Il faut que tu modifie ton operator[], il doit renvoyer une référence sinon on ne peut pas écrire v1[i]=...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Telem& operator[](int i);

  6. #6
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    merci pour vos reponses !!

    jmv merci pour la correction de la reference
    mais je dois mettre ton code dans une methode mais moi j e veux affecter directement tu vois !!!!

    JolyLoic : g consulté le lien du thread mais j'ai rien compris de la solution.
    est ce que je dois creer un constructeur de conversion ??? !!!
    genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Vector<float> operato Vector<int>(){ }
    si oui qu'est ce que je dois ecrire dedans

    merci encore !!!!

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Tu dois effectivement ecrire un constructeur de conversion (et non un operateur de cast comme ce que tu as écris)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template<class T>
    class Vecteur
    {
        template <class U> Vecteur(const Vecteur<U>& v)
        {
            // Conversion et copie des éléments de v dans this
        }
     
        // ...
    };

  8. #8
    jmv
    jmv est déconnecté
    Membre confirmé Avatar de jmv
    Profil pro
    Enseignant
    Inscrit en
    Mai 2004
    Messages
    395
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mai 2004
    Messages : 395
    Points : 603
    Points
    603
    Par défaut
    Citation Envoyé par mehdi_tn
    j'ai deux instances
    Vecteur<int> v1;
    et
    Vecteur<float> v2;
    Comment puis-je affecter la deuxieme instance a la premiere ??
    v1=v2;
    Citation Envoyé par Loulou24
    Tu dois effectivement ecrire un constructeur de conversion ...
    ça ne serait pas plutôt un operator= qu'il faudrait définir ici ???

  9. #9
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Non, car on pourrait avoir ce genre d'abberation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Vecteur<int> v1;
    Vecteur<double> v2 = v1; // Erreur (appel d'un constructeur, qui n'existe pas)
    v2 = v1; // Ok (appel de l'opérateur d'affectation)
    En général, on ne code toujours qu'un opérateur =, prenant en paramètre un objet de même type, et on laisse le soin aux constructeurs d'effectuer les diverses conversions.

  10. #10
    jmv
    jmv est déconnecté
    Membre confirmé Avatar de jmv
    Profil pro
    Enseignant
    Inscrit en
    Mai 2004
    Messages
    395
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mai 2004
    Messages : 395
    Points : 603
    Points
    603
    Par défaut
    Oui, c'est vrai, ça marche aussi comme ça.

  11. #11
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    et moi qui croyais etre un bon programmeur !!!

    deja pour implementer la solution dans ma classe Vector c l'embrouille parce qu'elle prends 3 parametres dans la construction generique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template <class Telem=int,int N=0,Telem zero=0>
    et j'ai eu plusieurs erreurs lors de la compilation que je posterais si je n'ai pas reussi à les resoudre.
    Enfin j'ai creé une autre classe plus simple qui prend seulement le type generique et voici ma classe appliquée à la solution :

    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
     
    template <class U>
    class Vecteur  
    {
    public:
    	Vecteur(int taille){tete=0;lataille=taille;tab= new U[taille];};
    template <class V> Vecteur(const Vecteur<V> & v)
                    {
                        for(int i=0;i<lataille;i++)
                            tab[i]=(U)v.getTab()[i];
                    };
    	void insert(U val){tab[tete]=val;tete++;};
    	U* getTab(){return tab;};
    	virtual ~Vecteur();
    private:
    	int lataille;
    	int tete;
    	U *tab ;
     
    };
    j'ai été obligé d'utiliser le getter getTab car si je fai com ca

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(int i=0;i<lataille;i++)tab[i]=(U)v.tab[i];}
    j'aurais cette erreur:

    error C2248: 'tab' : cannot access private member declared in class 'Vecteur<int>'
    vecteur.h(23) : see declaration of 'tab'
    test.cpp(12) : see reference to function template instantiation '__thiscall Vecteur<float>::Vecteur<float>(const class Vecteur<int> &)' being compiled


    Mais maintenant en utilisant getTab j'ai cette erreur:
    getTab' : cannot convert 'this' pointer from 'const class Vecteur<int>' to 'class Vecteur<int> &'

    J'ai une petite confusion dans ma tete :
    lors de l'appel de ce constructeur est-ce que le pointeur this est referencé par v ?? Sinon pourquoi l'erreur surgit !!!

    Merci d'avance

  12. #12
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    error C2248: 'tab' : cannot access private member declared in class 'Vecteur<int>'
    Oui, car Vecteur<U> et Vecteur<V> sont deux classes bien distinctes, qui n'ont donc aucun privilège l'une sur l'autre.
    Typiquement pour les accesseurs de ce genre, il faut deux versions : une const et une non-const. Ici il te manque la version const de getTab() pour faire fonctionner ton code (car le vecteur duquel tu appelles cette fonction est lui-même const).

    deja pour implementer la solution dans ma classe Vector c l'embrouille parce qu'elle prends 3 parametres dans la construction generique
    Tu as plusieurs solutions, il suffit de déterminer quels paramètres templates les 2 vecteurs doivent avoir en commun pour pouvoir être copiés :

    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
    template <class Telem=int,int N=0,Telem zero=0>
    class Vecteur
    {
    public :
     
        template <class Telem2,int N2,Telem2 zero2> Vecteur(const Vecteur<Telem2, N2, zero2>& v);
     
    // Ou alors
     
        template <class Telem2> Vecteur(const Vecteur<Telem2, N, zero>& v);
     
    // Ou encore...
     
        template <class Telem2, Telem2 zero2> Vecteur(const Vecteur<Telem2, N, zero2>& v);
    };
    Si ton vecteur doit posséder le même N et le même zero que celui que tu vas lui affecter, alors il faudra utiliser la 2eme version. Si par contre il n'y a aucune contrainte (ie. n'importe quel Vecteur<X, Y, Z> peut être copié dans un Vecteur<A, B, C>) alors tu peux utiliser la 1ere, etc...

  13. #13
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    Merci loulou pour tes reponses mais ca ne veut encore pas fonctionner !!!


    Typiquement pour les accesseurs de ce genre, il faut deux versions : une const et une non-const
    normalement on ne peut pas surcharger les fonctions sans modifier les arguments !!! ???

    donc je me re explique :
    voici ma class comme tu m'a dis de faire :

    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
     
    template<class U>
    class Vector  
    {
    public:
    	Vector(int lataille)
                     {
                          tete=0;
                          taille=lataille;
                          tab=new U[lataille];
                      };
    	template <class V> Vecteur(const Vector<V> & v)
                    {
                          for(int i=0;i<lataille;i++)
                                 tab[i]=(U)v.getTab()[i];
                    };
    	void insert(U val)
                    {
                         tab[tete]=val;
                         tete++;
                      };
    	U* getTab() const 
                      {
                           return tab;
                       };
    	U* getTab()
                      {
                           return tab;
                       };
    	virtual ~Vector()
                        {
                           delete [] tab;
                         };
    private:
    int taille;
    int tete;
    U * tab;
     
    };
    code edité apres la correction de JolyLoic .

    et voila mon main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int main(int argc, char* argv[])
    {
    Vector<int> v1(5);
    Vector<float> v2(5);
    v1.insert(2);
    v2.insert(2.6f);
     
    v1=v2;
     
    return 0;
    }
    et l'erreur est :

    binary '=' : no operator defined which takes a right-hand operand of type 'class Vector<float>' (or there is no acceptable conversion)

    Pourtant j'ai bien suivi ce que t'as indiqué et mon programme a encore un probleme lors du cast. Peut etre que t'as oublié quelques choses !!!!!

    STP LOULOU essai de resoudre mon probleme je comptes vraiment sur toi !!

  14. #14
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par mehdi_tn
    Merci loulou pour tes reponses mais ca ne veut encore pas fonctionner !!!


    Typiquement pour les accesseurs de ce genre, il faut deux versions : une const et une non-const
    normalement on ne peut pas surcharger les fonctions sans modifier les arguments !!! ???
    As-tu essayé ?
    Le code suivant est autorisé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class A
    {
      int f();
      int f() const;
    };
    Si tu veux une image pour mieux fixer les idées, le code que j'ai écrit revient à peut près au code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    // Pas du C++
    class A
    {
      int f(A* this);
      int f(A const * this);
    };
    Et là, tu retrouve ta règle un peu simplifiée des arguments différents.

    Typiquement, pour un vecteur de T, on définira un operator[] qui retournera un T&, et un operator[] const qui retournera un T const &.

  15. #15
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    merci JolyLoic.
    J'ai bien compris pourquoi le compilateur accepte const sans changer d'argument mais le probleme et que l'affectation ne fonctionne pas encore !!! Tu vois l'erreur que j'ai !!!

  16. #16
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template <class V> Vecteur(const Vector<V> & v)
    Bête erreur de frappe : tu as "Vecteur" au lieu de "Vector".

  17. #17
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut

    La honte ( sans commentaire pour la faute de frappe)
    Merci loulou pour ton aide mon probleme est enfin resolu.
    T'es mon nouveau idole du langage C++ ( apres Mr stroustrup "le createur de C++ pour ceux qui ne le conaissent pas").
    Envoie moi ta photo pour l'accrocher dans ma chambre :o

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

Discussions similaires

  1. Eclipse UML & classes generique & XMI
    Par bruno_pages dans le forum Autres
    Réponses: 3
    Dernier message: 18/03/2010, 09h30
  2. Affectation de classe de référence.
    Par label55 dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 19/02/2009, 15h09
  3. Classe generique java
    Par keub51 dans le forum Langage
    Réponses: 1
    Dernier message: 07/09/2007, 09h11
  4. creer une class generique factory
    Par Battosaiii dans le forum Langage
    Réponses: 1
    Dernier message: 26/07/2007, 13h56
  5. Pb de classe generique
    Par MicroPuce dans le forum Langage
    Réponses: 2
    Dernier message: 11/11/2006, 14h01

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