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 :

[débutant] utilisation d'une classe template dans une autre


Sujet :

Langage C++

  1. #1
    Membre éprouvé
    Avatar de thecaptain
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Décembre 2003
    Messages
    919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Décembre 2003
    Messages : 919
    Points : 1 210
    Points
    1 210
    Par défaut [débutant] utilisation d'une classe template dans une autre
    Salut à tous,

    Navré de reposter le message, mais le sujet précédent étant résolu, je pense que j'aurais plus de chance d'avoir une réponse
    J'essaie de coder la classe Queue (pour exercice donc). Jusque la pas de souci. Cependant, pensant à devoir coder Stack par après, j'ai fait une classe template DataNode qui se présente comme suit :
    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
    //DataNode.h
    #ifndef DATANODE_H
    #define DATANODE_H
     
    namespace list
    {
        template <typename T>
        class DataNode
        {
            public:
                    					DataNode(T* data); //constructor
                    void 				setData(T* data); //set the data of the node
                    T* 					getData(); //get the data of the node
     
            protected:
                    DataNode<T>*       	next; //next node
                    DataNode<T>*       	previous; //previous node      
     
            private:
            		void			   	init(); //init the node
                    T*                 	data_; //data of the DataNode
        };
    };
     
    #endif
    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
    //DataNode.ccp
    #include "DataNode.h"
     
    namespace list
    {
    	//------------//
    	//Constructors//
    	//------------//
        template <typename T>
        DataNode<T>::DataNode(T* data)
        {
        	init();
            setData(data);
        }
     
    	//--------------//
    	//Public methods//
    	//--------------//
        template <typename T>
        void DataNode<T>::setData(T* data)
        {
            data_ = data;
        }
     
        template <typename T>
        T* DataNode<T>::getData()
        {
            return data_;
        }
     
        //---------------//
        //Private methods//
        //---------------//
        template <typename T>
        void DataNode<T>::init()
        {
            //init the pointer
            next = 0;
            previous = 0;
        }
    };
    jusque la pas de souci, ca compile nickel et ca marche Le souci c'est de l'intégrer dans ma classe Queue qui est elle aussi un template. Je l'ai codée comme ceci :
    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
    //Queue.h
    #ifndef QUEUE_H_
    #define QUEUE_H_
     
    #include "BasicList.h"
    #include "DataNode.cpp"
     
    namespace list
    {
    	template <typename T>
    	class Queue : public list::BasicList
    	{
    		public:
    							Queue(); //constructor
    			DataNode<T>*	getFirst(); //get the first node
    			DataNode<T>*	getLast(); //get the last node
    			int				size(); //get the size
            	void			add(T* data); //add an object
            	void			addNode(DataNode<T>* node); //add a node
            	T*				remove(); //remove an object
            	DataNode<T>*	removeNode(); //remove a node
     
    		private:
    			int				tSize; //size of the queue
    			DataNode<T>*	tFirst; //first node
    			DataNode<T>*	tLast; //last node
    	};
    }
     
    #endif
    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
    //Queue.ccp
    #include "Queue.h"
    #include "DataNode.h"
     
    namespace list
    {
    	//-----------//
    	//Constructor//
    	//-----------//
    	template <typename T>
    	Queue<T>::Queue()
    	{
    		tSize = 0;
    		tFirst = 0;
    		tLast = 0;
    	}
     
    	//--------------//
    	//Public methods//
    	//--------------//
    	template <typename T>
    	DataNode<T>* Queue<T>::getFirst()
    	{
    		return tFirst;
    	}
     
    	template <typename T>
    	DataNode<T>* Queue<T>::getLast()
    	{
    		return tLast;	
    	}
     
    	template <typename T>
    	int	Queue<T>::size()
    	{
    		return tSize;
    	}
     
    	template <typename T>
    	void Queue<T>::add(T* data)
    	{
    		DataNode<T> no(data);
    		addNode(&no); //la il me sort une erreur
    	}
     
    	template <typename T>
    	void Queue<T>::addNode(DataNode<T>* node)
    	{
    		//check the size
    		if (tSize == 0)
    		{
    			tLast = node;
    			tFirst = node;
    		}
     
    		//add the node at the end
    		else
    		{
    			tLast.next = node; //ici aussi erreur
    			node.previous = tLast; //la aussi
    			tLast = node;
    		}
     
    		//increment the size
    		tSize++;
    	}
     
    	template <typename T>
    	T* Queue<T>::remove()
    	{
    		return (tSize == 0) ? 0 : removeNode().getData(); //erreur :(
    	}
     
    	template <typename T>
    	DataNode<T>* Queue<T>::removeNode()
    	{
    		//check the size
    		if (tSize == 0)
    		{
    			return 0;	
    		}
     
    		//if there is only one node
    		if (tSize == 1)
    		{
    			tLast = 0;
    		}
     
    		//remove the node
    		DataNode<T>* removed = tFirst;
    		tFirst = removed.next; //encore une erreur
    		if (tFirst != 0)
    		{
    			tFirst.previous = 0; //et la aussi
    			removed.next = 0; //et ici aussi
    		}
     
    		//decrement the size
    		tSize--;
     
    		//return the removed object
    		return removed;
    	}
    }
    J'ai rapidos fait le main ci-dessous :
    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
    //main.ccp
    #include "Main.h"
    #include <iostream>
    #include "ch/thecaptain/data/list/Queue.cpp"
     
    using namespace std;
    using namespace list;
     
    //template class Queue<int>; <-- j'ai trouvé ca sur
    //http://www.parashift.com/c++-faq-lite/templates.html
    //mais ca a pas l'air de marcher
     
    Main::Main()
    {
    };
     
    int main()
    {
    	int k = 15;
    	Queue<int> q;
    	q.add(&k); //la il me dit erreur
     
    	int* p = q.remove(); //la aussi
    	k = *p;
     
    	cout << k << endl;
     
    	return 0;
    };
    En bref, il me sort les erreurs suivantes (que j'ai de la peine à comprendre) :
    Citation Envoyé par le compilo
    Queue.cpp: In member function `T* list::Queue<T>::remove() [with T = int]':
    Main.cpp:20: instantiated from here
    Queue.cpp:70: request for member `getData' in `this->list::Queue<T>::removeNode() [with T = int]()', which is of non-aggregate type `list:ataNode<int>*'
    Queue.cpp: In member function `void list::Queue<T>::addNode(list:ataNode<T>*) [with T = int]':
    Queue.cpp:42: instantiated from `void list::Queue<T>::add(T*) [with T = int]'
    Main.cpp:18: instantiated from here
    Queue.cpp:58: request for member `next' in `this->list::Queue<int>::tLast', which is of non-aggregate type `list:ataNode<int>*'
    Queue.cpp:59: request for member `previous' in `node', which is of non-aggregate type `list:ataNode<int>*'
    Queue.cpp: In member function `list:ataNode<T>* list::Queue<T>::removeNode() [with T = int]':
    Queue.cpp:70: instantiated from `T* list::Queue<T>::remove() [with T = int]'
    Main.cpp:20: instantiated from here
    Queue.cpp:90: request for member `next' in `removed', which is of non-aggregate type `list:ataNode<int>*'
    Queue.cpp:93: request for member `previous' in `this->list::Queue<int>::tFirst', which is of non-aggregate type `list:ataNode<int>*'
    Queue.cpp:94: request for member `next' in `removed', which is of non-aggregate type `list:ataNode<int>*'
    Enfin, pour info, j'utilise Eclipse avec le plugin CDT avec le compilateur de dev-cpp (mingw32). Comment éclaircir tout ceci ?

    Merci d'avance

    @++
    Libzippp (C++)
    Lost in AStorm

  2. #2
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
       DataNode<T>* Queue<T>::removeNode()
    ....
          DataNode<T>* removed = tFirst; 
          tFirst = removed.next; //encore une erreur 
          if (tFirst != 0) 
          { 
             tFirst.previous = 0; //et la aussi 
             removed.next = 0; //et ici aussi 
          }
    removed, tfirst sont des pointeurs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
          tFirst = removed->next;  
          if (tFirst != 0) 
          { 
             tFirst->previous = 0; 
             removed->next = 0; 
          }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DataNode<T>*   removeNode();
    ....
       T* Queue<T>::remove() 
       { 
          return (tSize == 0) ? 0 : removeNode().getData(); //erreur :( 
       }
    removeNode renvoie un pointeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     return (tSize == 0) ? 0 : removeNode()->getData();
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
       void Queue<T>::addNode(DataNode<T>* node) 
    ....
          else 
          { 
             tLast.next = node; //ici aussi erreur 
             node.previous = tLast; //la aussi
    idem pour tLast et node
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
             tLast->next = node; 
             node->previous = tLast;
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  3. #3
    Membre éprouvé
    Avatar de thecaptain
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Décembre 2003
    Messages
    919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Décembre 2003
    Messages : 919
    Points : 1 210
    Points
    1 210
    Par défaut
    Salut et merci pour la réponse

    Effectivement, maintenant ca passe la compile ^^ J'ai encore un peu de mal à saisir l'action de l'opérateur ->.
    Par contre maintenant j'ai une erreur à l'exécution sur la méthode remove
    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
    template <typename T>
    	T* Queue<T>::remove() //ici ca plante à l'exécution
    	{
    		return (tSize == 0) ? 0 : removeNode()->getData();
    	}
     
    	template <typename T>
    	DataNode<T>* Queue<T>::removeNode() //cette méthode marche nickel
    	{
    		//check the size
    		if (tSize == 0)
    		{
    			return 0;	
    		}
     
    		//if there is only one node
    		if (tSize == 1)
    		{
    			tLast = 0;
    		}
     
    		//remove the node
    		DataNode<T>* removed = tFirst;
    		tFirst = removed->next;
    		if (tFirst != 0)
    		{
    			tFirst->previous = 0;
    			removed->next = 0;
    		} 
     
    		//decrement the size
    		tSize--;
     
    		//return the removed object
    		return removed;
    	}
    je dois faire une erreur de pointeur mais je vois pas pourquoi Le plantage c'est un truc du genre "le bloc de mémoire à l'adresse 0x0000350923 ne peut pas être written"... une idée ?

    merci d'avance

    @++

    ps. la classe Queue est une friend de DataNode
    Libzippp (C++)
    Lost in AStorm

  4. #4
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Par contre maintenant j'ai une erreur à l'exécution sur la méthode remove
    Je ne vois pas à priori d'erreurs sur cette fonction. Mais, celle-ci me pose problème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     template <typename T> 
       void Queue<T>::add(T* data) 
       { 
          DataNode<T> no(data); 
          addNode(&no); //la il me sort une erreur 
       }
    En effet, no est une variable locale qui sera détruite à la sortie de la fonction. Or c'est l'adresse de cette variable détruite que tu stockes. Ensuite, quand tu fais le remove, l'adresse est dans les décors. C'est peut être l'explication si j'ai bien suivi ton code (ce qui n'est pas sur).
    Crée no par allocation dynamique (new) pour assurer sa survie et pense au delete.
    J'ai encore un peu de mal à saisir l'action de l'opérateur ->.
    L'opérateur . permet d'accéder aux champs d'une classe, d'une structure ou d'une union. Si tu as un pointeur p sur une classe (ou...), pour accéder aux champs, il faut déréférencer le pointeur pour accéder à la classe ,*p, et ensuite accéder au champ : (*p).champ. Cette situation est très fréquente et aboutit à cette écriture lourde. Elle peut être avantageusement remplacée par la notation équivalente p->Champ
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  5. #5
    Membre éprouvé
    Avatar de thecaptain
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Décembre 2003
    Messages
    919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Décembre 2003
    Messages : 919
    Points : 1 210
    Points
    1 210
    Par défaut
    Salut,

    merci pour les éclaircissements En effet j'avais encore un peu de peine à différencier les variables dans la pile et dans le tas ! Donc en mettant ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <typename T>
       void Queue<T>::add(T* data)
       {
          DataNode<T>* no = new DataNode<T>(data);
          addNode(no);
       }
    tout marche nickel

    @++
    Libzippp (C++)
    Lost in AStorm

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 22/11/2010, 14h15
  2. Réponses: 4
    Dernier message: 20/10/2009, 08h54
  3. Fonction template dans une classe template
    Par mister3957 dans le forum Langage
    Réponses: 9
    Dernier message: 08/07/2008, 12h11
  4. Réponses: 8
    Dernier message: 20/07/2007, 14h28
  5. Class interne dans une classe template
    Par MatRem dans le forum Langage
    Réponses: 26
    Dernier message: 15/06/2006, 10h45

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