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 pile generique avec template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Décembre 2008
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 35
    Par défaut Classe pile generique avec template
    Salut a tous,j'ai un probleme avec les template ,j'ai réaliser une petite classe pile
    qui marche très bien mais quand j'ai voulus la rendre generique je suis tembé dans de plusieurs erreurs.

    J'ai voulues envoyer tous le projet en pièce jointe mais ça n'a pas marché,bon je l'envoie avec la balise code.
    S'il vous plais compiler le et montrer moi mes erreurs.

    Merci d'avance.

    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
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
     
    //le fichier noeud.h
    #include "iostream.h"
    #include "stdlib.h"
    #include "time.h"
     
     
    template <class T> class noeud
    {
    public:
    	noeud(T ielt=0,noeud<T>* isvt=NULL);
     
    private:
    	friend class pile;
    	T elt;
    	noeud<T>* svt;
    };
    //le fichier pile.h 
    #include "noeud.h"
     
    template <class T> class pile
    {
    public:
    	pile();
    	~pile();
    	void empiler(T);
    	void depiler();
    	void afficher();
    private:
    	noeud<T>* tete;
    };
    //le fichier pile.cpp
    #include "pile.h"
     
     
    pile<T>::pile()
    {
    	tete=NULL;
    }
    template <class T> pile<T>::~pile()
    {
    	while(tete!=NULL)
    	{
    		depiler();
    	}
    	delete tete;
    }
     
    template <class T> void pile<T>::empiler(T val)
    {
    	noeud<T>* n=new noeud<T>(val);
     
    	n->elt=val;
    	n->svt=tete;
    	tete=n;
    }
     
    template <class T> void pile<T>::depiler()
    {
    	noeud<T>* p;
    	if(tete!=NULL)
    	{
    		p=tete;
    		tete=tete->svt;
    	}
    	delete p;
    }
     
    template <class T> void pile<T>::afficher()
    {
    	if(tete==NULL)
    		cout<<"la pile est vide";
    	if(tete!=NULL)
    	{
    		noeud<T>* n=tete;
    		while(n!=NULL)
    		{
    			cout<<"<"<<n->elt<<"> "<<endl;
    			n=n->svt;
    		}
    	}
    	cout<<endl;
    }
    //le fichier noeud.cpp
    #include "noeud.h"
     
    template <class T> noeud<T>::noeud(T ielt,noeud<T>* isvt)
    {
    	elt=ielt;
    	svt=isvt;
    }
    //le fichier main.cpp
    #include "pile.h"
     
    main()
    {
    	pile <int> p;
     
    	p.empiler(7);
    	p.empiler(8);
    	p.empiler(9);
    	p.empiler(10);
    	p.afficher();
    	p.depiler();
    	p.depiler();
    	p.depiler();
    	p.depiler();
    	p.afficher();
     
     
    }

  2. #2
    Invité de passage
    Inscrit en
    Avril 2009
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 1
    Par défaut
    Changè le code suivant

    friend class pile;

    pour

    template<typename U> friend class pile;

    C'est qui a provoqué erreurs dans mon vs2008.
    J'espère que aide vous.

  3. #3
    Membre averti
    Inscrit en
    Décembre 2008
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 35
    Par défaut
    Merci pour la reponse, de 22 erreurs il en reste que 6,dont plusieurs erreurs
    <end parse> que je ne comprend pas.

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Peux-tu poster l'intégralité du message d'erreur ?

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Je voudrais déjà attirer ton attention sur quelques points assez particuliers:

    Le premier est que l'implémentation des fonctions template doit être placée dans le fichier d'en-tête ou, de manière indirecte, dans un fichier (dont l'extension ne sera pas cpp), qui sera inclu dans le fichier d'en-tête.

    La raison en est qu'il est impossible pour le compilateur de créer le code binaire d'une fonction template (ou d'une fonction membre d'une classe template) tant qu'il ne sait pas quel type réellement utiliser.

    Il doit donc disposer du code des fonctions pour chaque implémentation particulière qu'il trouvera dans le projet.

    Pour y arriver, il faut, bah, que le code des fonctions soit accessible depuis le fichier d'en-tête

    Le deuxième point est un détail, mais, typiquement, la classe Noeud devrait être imbriqué dans la classe Pile.

    En effet, le noeud ne doit être manipulé que dans un contexte de pile, et il n'y a donc pas de raison particulière de laisser l'utilisateur de ta classe s'en servir autrement

    Cela se traduira par un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <typename T>
    class Pile
    {
        public:
            template<typename T>
            Noeud
            {
                /* contenu du noeud */
            };
            /* contenu de Pile */
    };
    Le point suivant sur lequel je souhaiterais attirer ton attention est le constructeur de ton noeud:

    Non seulement, il est inutile de donner la valeur par défaut 0 à la valeur de l'élément (ielt), mais c'est également dangereux:

    C'est inutile parce que, il n'y a rien à faire, il faut disposer d'un élément valide lors de la construction du noeud (même si plusieurs points de vue devraient être envisagés): Si tu n'en dispose pas, tu ne peux pas décemment envisager d'initialiser ton objet de type Noeud : un noeud ne peut pas être "défaut constructible"

    C'est dangereux parce que tu semble considérer qu'une valeur nulle sera d'office cohérente avec une valeur par défaut, mais ce ne sera pas forcément le cas...

    Et nous pouvons presque considérer que cette valeur par défaut sera plus souvent incorrecte que cohérente dans le sens où elle ne sera cohérente que si l'élément est un type primitif ou un pointeur (et encore)

    De plus, il est inutile de passer un pointeur vers l'élément suivant (précédent, en fait, dans une pile) au constructeur, et partant de lui donner une valeur par défaut:

    Lorsque tu construit ton noeud, le pointeur vers le noeud suivant doit être d'office initialisé à NULL et seule la pile doit non seulement être capable d'y accéder, mais aussi savoir que ce pointeur existe

    Ensuite, il ne faut pas oublier que le noeud doit être copiable et assignable, mais que le comportement par défaut du compilateur n'est pas adapté à la copie, du fait de la présence du pointeur vers l'élément précédent dans la pile (il en est d'ailleurs de même pour la pile ):

    Le comportement implémenté par défaut par le compilateur est en effet la copie membre à membre, ce qui se traduit par le fait que, en cas de copie d'un noeud, tu te retrouvera avec plusieurs noeuds (l'original et la copie) pointants vers un seul et même noeud précédent.

    Cet état de fait a de fortes chances de mener très rapidement à des doubles libérations de la mémoire (le fait d'essayer d'invoquer plus d'une fois delete sur un élément alloué dynamiquement).

    Or une double libération de la mémoire mène systématiquement à des catastrophes, d'ampleur inconnue: cela peut, dans le meilleur des cas, mener au plantage de ton application, dans le pire, provoquer le lancement une ogive nucléaire sur Paris... ou pire encore

    Un dernier point à prendre en compte (enfin, pour l'instant, histoire de ne pas partir sur l'écriture d'un roman et te laisser l'occasion d'assimiler à ton aise les points évoqués), c'est qu'il est très bien de disposer d'un noeud, mais qu'il faut, aussi, s'assurer de pouvoir accéder à la valeur du noeud...

    Tu devra donc envisager de définir les opérateurs * et -> pour donner l'accès à cette valeur

    Malgré les apparences, je t'ai donné ici la version "courte" des explications.

    Je vais te laisser cogiter un peu dessus, histoire de te donner une chance de trouver la solution par toi-même.

    Mais n'hésite pas à poser toutes les questions que tu veux si un des points évoqué reste ténébreux pour toi
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre averti
    Inscrit en
    Décembre 2008
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 35
    Par défaut
    Salut a tous ,j'ai grouper tout dans un header et il me reste 7 erreur que je n'ai pas compris.
    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
    #include <iostream.h>
    #include <stdlib.h>
    #include <time.h>
     
     
    template <class T> class pile
    {
    public:
    	template <class T> class noeud
    	{
    	public:
            template <class T> noeud(T ielt,noeud<T>* isvt)
    		{
    			elt=ielt;
    			svt=isvt;
    		}
    	private:
    		T elt;
    		noeud<T>* svt;
    	};
        template <class T> pile()
    	{
    		tete=NULL;
    	}
    	~pile()
    	{
    		while(tete!=NULL)
    		{
    			depiler();
    		}
    		delete tete;
    	}
     
    	template <class T> void empiler(T val)
    	{
    		noeud<T>* n=new noeud<T>(val);
     
    		n->elt=val;
    		n->svt=tete;
    		tete=n;
    	}
     
    	template <class T> void depiler()
    	{
    		noeud<T>* p;
    		if(tete!=NULL)
    		{
    			p=tete;
    			tete=tete->svt;
    		}
    		delete p;
    	}
    	/*
    	ostream& operator<<(ostream out,pile& p)
    	{
    		if(p.tete!=NULL)
    		{
    			noeud* n=p.tete;
    			while(n!=NULL)
    			{
    				out<<"<"<<n->elt<<"> ";
    				n=n->svt;
    			}
    		}
    		return out;
    	}
    	*/
    	template <class T> void afficher()
    	{
    		if(tete==NULL)
    			cout<<"la pile est vide";
    		if(tete!=NULL)
    		{
    			noeud<T>* n=tete;
    			while(n!=NULL)
    			{
    				cout<<"<"<<n->elt<<"> "<<endl;
    				n=n->svt;
    			}
    		}
    		cout<<endl;
    	}
    	private:
    		noeud<T>* tete;
    };
    Le main()
    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
    #include "pile.h"
     
     
    main()
    {
    	pile <int> p;
     
    	p.empiler(7);
    	p.empiler(8);
    	p.empiler(9);
    	p.empiler(10);
    	p.afficher();
    	p.depiler();
    	p.depiler();
    	p.depiler();
    	p.depiler();
    	p.afficher();
     
     
    }
    les erreurs.
    :\Program Files\Microsoft Visual Studio\MyProjects\Pile T\main.cpp(6) : error C2512: 'pile<int>::pile<int>' : no appropriate default constructor available
    C:\Program Files\Microsoft Visual Studio\MyProjects\Pile T\main.cpp(12) : error C2783: 'void __thiscall pile<int>::afficher(void)' : could not deduce template argument for 'T'
    C:\Program Files\Microsoft Visual Studio\MyProjects\Pile T\main.cpp(13) : error C2783: 'void __thiscall pile<int>::depiler(void)' : could not deduce template argument for 'T'
    C:\Program Files\Microsoft Visual Studio\MyProjects\Pile T\main.cpp(14) : error C2783: 'void __thiscall pile<int>::depiler(void)' : could not deduce template argument for 'T'
    C:\Program Files\Microsoft Visual Studio\MyProjects\Pile T\main.cpp(15) : error C2783: 'void __thiscall pile<int>::depiler(void)' : could not deduce template argument for 'T'
    C:\Program Files\Microsoft Visual Studio\MyProjects\Pile T\main.cpp(16) : error C2783: 'void __thiscall pile<int>::depiler(void)' : could not deduce template argument for 'T'
    C:\Program Files\Microsoft Visual Studio\MyProjects\Pile T\main.cpp(17) : error C2783: 'void __thiscall pile<int>::afficher(void)' : could not deduce template argument for 'T'
    C:\Program Files\Microsoft Visual Studio\MyProjects\Pile T\main.cpp(18) : warning C4508: 'main' : function should return a value; 'void' return type assumed
    Error executing cl.exe.

    Pile T.exe - 7 error(s), 1 warning(s)

Discussions similaires

  1. Réponses: 10
    Dernier message: 11/04/2013, 16h22
  2. Réponses: 2
    Dernier message: 30/12/2009, 20h44
  3. Classe Liste générique avec template
    Par TNT89 dans le forum Langage
    Réponses: 9
    Dernier message: 09/05/2009, 15h14
  4. Difficultés avec template de classe
    Par Rniamo dans le forum Langage
    Réponses: 2
    Dernier message: 06/11/2008, 09h28
  5. Réponses: 9
    Dernier message: 19/05/2007, 15h28

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