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 :

[Debutant]Généricité & Héritage


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Par défaut [Debutant]Généricité & Héritage
    Bonsoir,

    Je suis entrain de concevoir mentalemet une classe seulement, il y a une inconnu.
    J'ai crée une liste doublement chainée générique et j'aurais aimé qu'elle prenne des classes ayant hérité d'une classe mère.

    exemple : saut,course hérite de mouvement.

    Seulement puis je en c++, créer la liste avec comme type Mouvement et après y ajouter les objets course et saut dedans ?

    Si c'est impossible comment contourner la chose ?

    merci d'avance

  2. #2
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Citation Envoyé par Drannor
    Bonsoir,

    Je suis entrain de concevoir mentalemet une classe seulement, il y a une inconnu.
    J'ai crée une liste doublement chainée générique et j'aurais aimé qu'elle prenne des classes ayant hérité d'une classe mère.

    exemple : saut,course hérite de mouvement.

    Seulement puis je en c++, créer la liste avec comme type Mouvement et après y ajouter les objets course et saut dedans ?

    Si c'est impossible comment contourner la chose ?

    merci d'avance
    C'est possible, tu dois utiliser le polymorphisme.
    Il faut pour cela créer une liste de pointeurs ou de références sur ta classe mère.

    Ensuite, dans ta liste, tu peux stocker des pointeurs ou références sur un objet d'une classe héritée.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Par défaut
    Ok mais en aucun cas ça marche si je rajoute clairement les objets dedans ?

    exemple :

    Saut saut ;
    Course cours ;
    ListeDoublementChainee<Mouvement> liste ;
    liste.add(saut);
    liste.add(cours);

    Je dois forcement passé par les adresses ou les pointeurs ?


    Merci beaucoup de ton aide.

  4. #4
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Tu peux utiliser des références :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListeDoublementChainee<Mouvement &> liste ;
    Et après faire simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    liste.add(saut);
    liste.add(cours);

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Par défaut
    merci beaucoup !!!

    Je vais tester tout ça !

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Citation Envoyé par Eusebe
    Tu peux utiliser des références :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListeDoublementChainee<Mouvement &> liste ;
    Et après faire simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    liste.add(saut);
    liste.add(cours);
    Pas vraiment, non.

    Je dois forcement passé par les adresses ou les pointeurs ?
    Oui.
    Tu as les pointer containers de boost qui font ça.

    Après tu peux aussi utiliser un conteneur spécial pour rendre les objets polymorphes. (du genre poly_obj<ClasseBase> obj = ClasseDerivee()
    Mais dans ce cas là, comme il n'y a pas encore de sémantiques de mouvement en C++, tu vas devoir te taper des copies coûteuses qu'on pourrait pourtant éviter.

  7. #7
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Citation Envoyé par loufoque
    Pas vraiment, non.
    Merci Loufoque, mais tu pourrais m'expliquer ce qui ne va pas ?
    Je sais parfaitement que je peux me planter, mais dans les souvenirs que j'ai de mes lectures, le polymorphisme fonctionne avec les références, non ?
    Alors qu'est-ce qui cloche dans ce que j'ai écris ?

    Merci d'avance pour tes explications éclairées...

  8. #8
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    On ne peut pas stocker des références dans un conteneur.

  9. #9
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Citation Envoyé par Laurent Gomila
    On ne peut pas stocker des références dans un conteneur.
    Mais si c'est lui qui crée son propre conteneur :
    Citation Envoyé par Drannor
    J'ai crée une liste doublement chainée générique
    Il doit pouvoir le faire de telle façon qu'il accepte les références, non ?

  10. #10
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 308
    Par défaut
    Non.
    C++ != Java. Les références ne sont pas des variables autonomes. Ce sont des alias, des raccourcis.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Par défaut
    Le truc c'est qu'on m'a appris mon objet sous java.
    donc j'avais une vision un peu java de la chose.
    Mais la je suis un peu perdu donc si on pouvait me montrer un exemple, j'en serais grés.

    Merci


    edit le code de ma listeDoublementChainee.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
    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
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    #ifndef LISTEDOUBLEMENTCHAINEEH
    #define LISTEDOUBLEMENTCHAINEEH
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #include <string.h>
     
    using namespace std;
     
    template <class T> class ListeDoublementChainee {
     
    	private : 
    		struct noeud{
    			int uid ;
    			T  element ;
    			int indice ;
    			struct noeud* previous;
    			struct noeud* next ; 		
    		};
    		typedef struct noeud noeud ;
     
     
    		int nbElement ;
    		noeud* racine  ; //point toujours sur le premier
    		noeud* pre ; //pre sera toujours sur le dernier élement de la liste
    		noeud* current ; //permet de se déplacer
     
     
    		void Initialisation();
     
    	public : 
    	//constructeur
    		ListeDoublementChainee();
     
    		void reinitialisation();
    //accesseur 	
    	//recuprer un element
    		T getElem(int i) const;
     
    	//connaitre le nbElement
    		int getNbElement() const;
     
    	//recuperer la racine
    		noeud getRacine() const{
    			return *racine ;
    		};
     
    	//recupere le noeud courrant
    		noeud getCurrent() const{
    			return *current ;
    		};
     
    	//recupere le noeud de fin
    		noeud getEnd() const{
    			return *pre ;
    		};
     
     
    	//recupere l'element courrant
    		int getCurrentIndice() const;
     
     
    	//recupere l'elemente de la racine
    	//recupere l'element courrant
    		T getRacineElem() const;
     
    	//recupere l'element courrant
    		T getCurrentElem() const;
     
    		int getEndIndice() const;
     
    		T getEndElem() const;
     
    //modificateur	
    	//replace le current sur l'objet le noeud donné en parametre
    	//en verifiant que le noeud est bien un de ceux de this
    		void setCurrent(noeud N);
     
    		void setCurrentElem(T obj);
     
     
    	//ajouter un element
    		void addElem(T obj);	
     
    		int addCurrentElem(T obj);
     
     
     
    	//supprimer un element
    		int delElem(int i);
     
     
    		//supprimer un element
    		int delCurrentElem();
     
     
    	//pour modifier l'element pointé par current
    		void changeElem(T obj);
     
     
    //methode	
    	//concatener deux chaines pour en obtenir une troisieme
    		void concacList(noeud L);
     
    	//pour deplacer le curseur de l'element courant
    		int moveCurrent(int i , char lr);
     
     
    	//pour deplacer le curseur de l'element courant et changer en même temps
    		int applyCurrent(int i , char lr , T obj);
     
    	//ramene me courant à la racine
    		void goCurrentRacine();
    		void goCurrentEnd() ;
     
    		void afficheCurrent() const;
     
     
    		void afficheToi() const;
     
    	//destructeur
    		~ListeDoublementChainee ();
    };
     
    #include "ListeDoublementChainee.cpp" 
    #endif

    code de ListeDoublementChainee.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
    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
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
     
    #ifdef LISTEDOUBLEMENTCHAINEEH
     
    template <class T> void ListeDoublementChainee<T>::Initialisation(){
    	racine = NULL ;
    	current = NULL ;
    	//pre = NULL ;
    	nbElement = 0 ;
    	};
     
    //constructeur
    	template <class T> ListeDoublementChainee<T>::ListeDoublementChainee(){
    		Initialisation();	
    	};
     
    //reinitialisation
    	template <class T> void ListeDoublementChainee<T>::reinitialisation(){
     
    		if (racine != NULL){
     
    			noeud * k = NULL ;
     
    			while(racine->indice < pre->indice){	
     
    				k = pre ;
     
    				pre = pre->previous ;
     
    				free(k);
     
    			};
    			free(pre);
     
    			Initialisation();
    	};
     
    	};
     
    //accesseur 	
    	//recuprer un element
    	template <class T> T ListeDoublementChainee<T>::getElem(int i) const{
    		noeud* p = racine ;
    		if (i > nbElement) return NULL ;
    		for (int j = 0 ; j != i ; j++){
    			p = p->next ;
    		}
    		return p->element ;
    	};
     
    	//connaitre le nbElement
    	template <class T> int ListeDoublementChainee<T>::getNbElement() const{
    		return nbElement ;
    	};
     
    	//manque trois fonctions voir dansle header
     
     
    	//recupere l'element courrant
    	template <class T> int ListeDoublementChainee<T>::getCurrentIndice() const{
    		return current->indice ;
    	};
     
     
    	//recupere l'elemente de la racine
    	//recupere l'element courrant
    	template <class T> T ListeDoublementChainee<T>::getRacineElem() const{
    		return racine->element ;
    	};
     
    	//recupere l'element courrant
    	template <class T> T ListeDoublementChainee<T>::getCurrentElem() const{
    		return current->element ;
    	};
     
    	template <class T> int ListeDoublementChainee<T>::getEndIndice() const{
    		return pre->indice ;
    	};
     
    	template <class T> T ListeDoublementChainee<T>::getEndElem() const{
    		return pre->element;
    	};
     
    //modificateur	
    	//replace le current sur l'objet le noeud donné en parametre
    	//en verifiant que le noeud est bien un de ceux de this
    	template <class T> void ListeDoublementChainee<T>::setCurrent(noeud N){
    		noeud* p = racine ;
     
    		for(int i = 0 ; i < nbElement ; i++){
    			if (N.uid == p->uid){current = p ; break;}
    			//printf("uid de N : %d / adresse de p %d \n",N.uid,p->uid);
    			//printf("valeur de N : %d \n",N.element);
    			p = p->next ;
    		}
     
    	};
     
    	template <class T> void ListeDoublementChainee<T>::setCurrentElem(T obj){
    		current->element = obj ;
     
    	};
     
     
    	//ajouter un element
    	template <class T> void ListeDoublementChainee<T>::addElem(T obj){
    		noeud *p = new noeud ;
    		p->uid = (int)this ; //sert a donner un numero unique
    		p->element = obj ;
    		p->indice = nbElement ;
    		p->previous = pre ;
    		p->next = NULL ;
     
     
    		if (nbElement == 0) {
    			racine = p ;
    			pre = racine ;
    			current = racine ; 
    		}else{ 
    			pre->next = p ;
    			pre = p ;
    		}
    		nbElement ++ ;
    	};	
     
    	template <class T> int ListeDoublementChainee<T>::addCurrentElem(T obj){
    		noeud *p = new noeud ;
     
    		if (nbElement != 0) {
    			p->uid = (int)this ; //sert a donner un numero unique
    			p->element = obj ;
    			p->indice = current->indice ;
     
    			p->next = current->next  ;
    			current->next->previous = p  ;
     
    			p->previous = current ;
    			current->next = p ;
     
    			while (p != NULL){
    				p->indice ++ ;
    				p = p->next ;
    			}
     
     
    			nbElement ++ ;
    			return 1 ;
    		}
    		return -1 ;
     
    	};
     
     
     
    	//supprimer un element
    	template <class T> int ListeDoublementChainee<T>::delElem(int i){
    		noeud* p = racine ;
    		noeud* avant = NULL ;
    		noeud* apres = NULL ;
     
    		if (i > (nbElement-1)) return -1 ;
     
    		//cas ou il n'y a qu'un element
    		if ((pre->indice == current->indice) && (current->indice == racine->indice)) {
    			racine = NULL;
    			current = NULL ;
    			pre = NULL ;
    			nbElement -- ;
    			return 1 ;
    		}
     
     
    		//mesure de précaution en cas de pb 
    		//si on supprime le dernier
    		if (pre->indice == i) pre = pre->previous ;
    		//si on supprimele premier
    		if (racine->indice == i) racine = racine->next ;
    		//si current est sur le dernier
    		if ((current->indice == i) && (current->indice == (nbElement-1))) current = current->previous ;
    		//si current est autre que sur le dernier
    		else  current = current->next ;
     
     
     
    		for (int j = 0 ; j != i ; j++){
    			avant = p ;
    			p = p->next ;
    			apres = p->next ;
    		}
     
    		delete p ;
    		avant->next = apres ;
     
    		if (apres != NULL) 
    		      apres->previous = avant ;
     
     
    		while (apres != NULL){
    			apres->indice -- ;
    			apres = apres->next ;
    		}
     
    		nbElement -- ;
    		return 1 ;
    	};
     
     
    		//supprimer un element
    	template <class T> int ListeDoublementChainee<T>::delCurrentElem(){
    		noeud* apres = NULL ;
    		noeud* supp =  current ;
     
    		if (nbElement == 0) return -1 ;
    		if (current->indice == 0) { //cas ou on supprimerait le premier
     
    			//cas ou il n'y a qu'un eleme
    			if (pre->indice == current->indice){
    				racine = NULL;
    				current = NULL ;
    				pre = NULL ;
    				nbElement -- ;
    				return 1 ;
    			}
     
    			//sinon
    			racine = racine ->next ;
    			current = current->next ;
     
    		}
     
     
    		else if (current->indice == (nbElement-1)){//cas ou on supprime le dernier
    			pre = pre->previous ;
    			current = current->previous ;
    		}
    		else {	//entre les deux
    			//on créait le pont	
    		current->previous->next = current->next ;
    		current->next->previous = current->previous ;
    		//on fait avancer le courant
    		current = current->next  ;
     
    		}
     
    		apres = current ;
     
    		//on ré indice les élements
    		while (apres != NULL){
    			apres->indice -- ;
    			apres = apres->next ;
    		}
     
     
     
    		//on libere l'element
    		delete supp ;
     
    		nbElement -- ;
    		return 1 ;
    	};
     
     
    	//pour modifier l'element pointé par current
    	template <class T> void ListeDoublementChainee<T>::changeElem(T obj){
    		current->element = obj ;
    	}
     
     
    //methode	
    	//concatener deux chaines pour en obtenir une troisieme
    	template <class T> void ListeDoublementChainee<T>::concacList(noeud L){
     
     
    		noeud *p = NULL ;
    		p = new noeud ;
    		noeud* temp ;
     
    		//on recopie le premier élément
    		p->element = L.element;
    		p->next = L.next ;
    		p->uid = pre->uid ;
     
    		nbElement ++ ;
    		p->indice = nbElement - 1; 
     
    		//on dechaine
    		//temp = pre->next ;
    		//temp->previous = NULL ;
     
    		//on chaine
    		pre->next = p ;
    		p->previous = pre ;
    		pre = p ;
     
    		//pour placer pre à la fin 
    		for (int j = 0 ; pre->next != NULL; j++){
     
    			//on recopie tous les noeuds
     
    			p = new noeud ;
     
     
    			//on recopie le premier élément 
    			p->element = pre->next->element;
    			p->uid = pre->uid ;
     
    			nbElement ++;
    			p->indice = nbElement - 1; 
     
    			//on dechaine
    			//temp = pre->next ;
    			//temp->previous = NULL ;
     
     
    			//on chaine
    			p->next = pre->next->next ;
    			pre->next = p ;
    			p->previous = pre ;
    			//on avance
    			pre = pre->next;
    		}
     
    	};
     
    	//pour deplacer le curseur de l'element courant
    	template <class T> int ListeDoublementChainee<T>::moveCurrent(int i , char lr){
    		if (i == -1) i = nbElement ;
     
    		switch(lr){
    			case 'l' : if ((current->indice - i) < 0) return -1 ;
    			else {
    				for (int j = 0 ; j < i ; j++) 
    					current = current->previous ;	
    			}
    			break ;
     
    			case 'r' : if((i + current->indice) >= nbElement)  return -1 ;
    			else {
    				for (int j = 0 ; j < i ; j++) 
    					//ne pas avoir un current null
    					current = current->next ;
    			}
    			break ;
     
    			default : return -1 ;
    		}
    		return 1 ;
    	};
     
     
    	//pour deplacer le curseur de l'element courant et changer en même temps
    	template <class T> int ListeDoublementChainee<T>::applyCurrent(int i , char lr , T obj){
    		if (i == -1) i = (nbElement - current->indice) ;
     
    		switch(lr){
    			case 'l' : if ((current->indice - i) < 0) return -1 ;
    			else {
    				for (int j = 0 ; j < i ; j++) {
    					current = current->previous ;
    					changeElem(obj);
    				};	
    			}
    			break ;
     
    			case 'r' : if((i + current->indice) >= nbElement) 
    			{cout<<"indice courant applycurrent "<<current->indice<<endl;
    			return -1 ;}
    			else {//+1 car si on veut modifier l'element sur lequel on est cela ne se fait pas
    				for (int j = 0 ; j < i+1 ; j++){ 
    					changeElem(obj);
    					//pour ne pas voir un current null
    					if (j < i) current = current->next ;
     
    				};
    			}
    			break ;
     
    			default : return -1 ;
    		}
    		return 1 ;
    	};
     
     
    	template <class T> void ListeDoublementChainee<T>::goCurrentRacine() {
    		current = racine ;
    	}
     
    	template <class T> void ListeDoublementChainee<T>::goCurrentEnd() {
    		current = pre ;
    	}
     
    	template <class T> void ListeDoublementChainee<T>::afficheCurrent() const{
    		if (current != NULL)
    			cout<<"Element courant : "<<current->element<<" indice : "<<current->indice<<endl;
    		else cout<<"La liste est vide"<<endl;
     
    	};
     
    	template <class T> void ListeDoublementChainee<T>::afficheToi() const{
    		noeud* p = racine ;
     
    		if (p != NULL){
    		cout<<"Uid de la liste : "<<racine->uid<<endl;
    		/*for (int i = 0 ; i < nbElement ; i++){
    			//printf("In for \n");
    			if (current->indice == i) 
    				cout<<"Element :*"<<p->element<<"* indice : "<<p->indice<<endl;
    			else 
    			        cout<<"Element : "<<p->element<<" indice : "<<p->indice<<endl;
    			p = p->next ;   
    		}*/
    		cout<<"Element indice : "<<p->indice<<endl;
    		p = p->next ; 
    		}
    		else cout<<"La liste est vide"<<endl;
    	};
     
    	//destructeur
    	template <class T> ListeDoublementChainee<T>::~ListeDoublementChainee (){
    		current = racine ;
    		while(nbElement > 0){
    		   delCurrentElem();
    		}
     
    	};
     
     
    #endif

  12. #12
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Quelques remarques, dans l'ordre où elles me viennent:

    - pourquoi redéfinir une liste doublement chaînée, il y a std::list<> pour ça?

    - tu as une utilisation bizarre de l'espace vertical. D'une part, tu mets beaucoup de lignes blanches, parfois doublées, d'autre part, tu mets du code sur la même ligne que les if, tu mets des accolades sur la même ligne que la déclaration des fonctions... ça me semble un peu contradictoire

    - tu utilises un mélange bizarre d'anglais et de français, de longs noms et d'abréviations dans ton choix d'identificateur (je prends par exemple trois champs de la liste: pre, racine, current)

    - en C++, il n'est pas nécessaire de répéter struct quand on déclare des membres (struct noeud*)

    - tu laisses défini le constructeur de copie et l'affectation du noeud. A priori, c'est le genre de classe dont copier les instances n'a guère de sens

    - dans l'interface publique, tu renvoies (et par copie, je me demande si ça a bien du sens, voir ci-dessus) des noeuds, mais cette classe n'est pas acessible de l'extérieur...

    - un intérêt des listes doublement chaînées, c'est de pouvoir facilement insérer et effacer à partir d'un itérateur vers le membre. Il n'y a pas d'itérateur disponible d'une part, et d'autre part tu maintiens la position de l'élément dans la liste, ce qui supprime une bonne partie de cet intérêt

    - caster un pointeur un int, pourquoi? pourquoi ne pas utiliser le bon type?

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Par défaut
    pourquoi redéfinir une liste doublement chaînée, il y a std::list<> pour ça?
    Avant tout c'était ma première classe en c++, et je suis débutant donc je ne connaissais pas l'existence de la classe std. Mais même si ça avait été le cas, j'ai envie de me créer mes bibliothèques et c'est un bonne exercice que d'écrire une liste doublement chainée.

    - tu as une utilisation bizarre de l'espace vertical. D'une part, tu mets beaucoup de lignes blanches, parfois doublées, d'autre part, tu mets du code sur la même ligne que les if, tu mets des accolades sur la même ligne que la déclaration des fonctions... ça me semble un peu contradictoire
    A désolé, j'utilise Kdevelop pour l'indentation. Les lignes blanches sont surement dû a des lignes de commentaires que j'ai enlevé (même si il en reste) mais j'ai pas vraiment prit la peine de nettoyer le code avant de le poster.

    - tu utilises un mélange bizarre d'anglais et de français, de longs noms et d'abréviations dans ton choix d'identificateur (je prends par exemple trois champs de la liste: pre, racine, current)

    j'utilise les terme dont j'ai le plus de facilité à me souvenir (et court de préférence ) pour coder rapidement.

    en C++, il n'est pas nécessaire de répéter struct quand on déclare des membres (struct noeud*)
    ça ca vient d'une superstition, pour annecdote en tp de C on devait créer des structure dans les headers et bizarrement lors de la compilation. Toutes les fonctions misent en extern prenant la structure, ne passait pas sauf si je rajouter le struc devant. Après j'ai gardé l'habitude.

    - tu laisses défini le constructeur de copie et l'affectation du noeud. A priori, c'est le genre de classe dont copier les instances n'a guère de sens

    - dans l'interface publique, tu renvoies (et par copie, je me demande si ça a bien du sens, voir ci-dessus) des noeuds, mais cette classe n'est pas acessible de l'extérieur...
    Là par contre je comprends pas la remarque.
    Je ne vois pas ou je copie les instances vu que je ne fait que renvoyer un objet.
    Et pourquoi la classe n'est elle pas accessible depuis l'extérieur ? Les méthodes sont pourtant public donc je peux y acceder depuis l'extérieur ?

    - un intérêt des listes doublement chaînées, c'est de pouvoir facilement insérer et effacer à partir d'un itérateur vers le membre. Il n'y a pas d'itérateur disponible d'une part, et d'autre part tu maintiens la position de l'élément dans la liste, ce qui supprime une bonne partie de cet intérêt
    En faite j'etais parti sur l'idée d'avoir une ancre la racine,et une fin toujours retenu par "le pointeur "pre".Et pour bouger dans cette liste avoir un pointeur Current qui se deplace et effectue des opérations comme rendre un éléments ou le modifier. Pour inserer, je peux le faire soit juste apres le current en le deplacent de maniere relative ou absolue si précédement je le remet sur la racine, ou direct après le dernier élément. Il en va de meme pour supprimer.

    Pour l'itérateur, j'avoue ne pas y avoir pensé et surtout je ne le maîtrise pas. En plus je n'y voyait pas d'utilité dans ce cas là.

    caster un pointeur un int, pourquoi? pourquoi ne pas utiliser le bon type?
    Si tu parles de cette ligne : p->uid = (int)this ; //sert a donner un numero unique
    C'était pour obtenir un numéro unique d'une maniere simple en attendant de trouver mieux.

    Voila.
    Enfin parcontre j'ai toujours pas trouvé de solution pour le problème premier

  14. #14
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Drannor
    j'utilise les terme dont j'ai le plus de facilité à me souvenir (et court de préférence ) pour coder rapidement.
    Ne pas être cohérent, c'est le plus sûr moyen que je connaisse pour avoir des difficultés à se souvenir sur le long terme. Et donc à perdre du temps. C'est aussi un bon moyen pour avoir dans un programme à la fois suivant et next et puis employer l'un pour l'autre. Donc à perdre du temps à débugger ce genre de problèmes...

    ça ca vient d'une superstition, pour annecdote en tp de C on devait créer des structure dans les headers et bizarrement lors de la compilation. Toutes les fonctions misent en extern prenant la structure, ne passait pas sauf si je rajouter le struc devant. Après j'ai gardé l'habitude.
    On ne programme pas avec des superstitions ni en essayant des choses jusqu'à ce qu'elles marchent sans comprendre pourquoi. C'est un bon moyen pour que ce qu'elles fassent soit subtilement différent de ce qui est nécessaire. Ça ira bien jusqu'à l'examen, la veille du code freeze pour un projet important, en démo chez le premier client de la boîte, ...

    Là par contre je comprends pas la remarque.
    Je ne vois pas ou je copie les instances
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    noeud getRacine() const
    Arrête tout de suite d'essayer de faire des templates et apprends le C++ en commençant par des choses plus simples.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Et pourquoi la classe n'est elle pas accessible depuis l'extérieur ?
    noeud est déclaré privé

    Si tu parles de cette ligne : p->uid = (int)this ; //sert a donner un numero unique
    C'était pour obtenir un numéro unique d'une maniere simple en attendant de trouver mieux.
    Pourquoi un int plutôt qu'un pointeur?

    Enfin parcontre j'ai toujours pas trouvé de solution pour le problème premier
    Tu veux du polymorphisme d'inclusion, il faut stocker dans ta liste des pointeurs ou des références, pas des valeurs.

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Par défaut
    Pour le noeud en privé j'avais pas tilté

    Pourquoi un int plutôt qu'un pointeur?
    Un uid pour moi est un numéro unique d'authentification donc un entier. Apres un pointeur est juste à mes yeux une case mémoire retenant une adresse. Donc je n'arrive pas à comprendre comment un pointeur peut devenir un uid. Dans ce cas je voulais simplement un numéro différent pour chaque liste créait, ne sachant comment l'obtenir (vu que le temps entre deux executions peut être inférieur a une seconde, time ne marchait pas et le pid est le même, random ayant une chance de donner deux fois le même nombre), j'ai décidé de prendre this et de le caster en int pour obtenir un numéro.

    C'est surement pas la bonne solution et je me suis pas assez penché sur le problème mais c'était pas primodial pour la suite et donc j'ai préféré continué à avancer et revenir dessus quand j'aurai eut une idée ou que ça devenait nécessaire.


    Arrête tout de suite d'essayer de faire des templates et apprends le C++ en commençant par des choses plus simples.
    Pour apprendre j'ai besoin d'exercer et lire des pdf de 250 pages, j'ai du mal surtout que j'avais fait du C avant celà et qu'a ma fac le C++ c'est 4 cours de deux heures en master 1. Donc autant l'apprendre seul. Pour ça j'ai rien trouvé de mieux dans mon cas que de me lancer dedans. Et manque de bol la première idée qui m'est venu est l'idée d'une liste doublement chainée en c++ et ayant fait du java je pensais au début que niveau généricité cela était la même chose.

    Sinon je vais essayer avec une listeDoublementChainee de pointeur de type void.
    En esperant que ça marche.

    Merci encore.

  16. #16
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Drannor
    Après qu'est ce qui est dit simples en c++ ?
    En tout cas pas l'écriture de template. L'utilisation de template est relativement simple, mais l'écriture d'une classe template demande pour commencer de pouvoir écrire cette classe pour un type donné sans problèmes. Ce n'est visiblement pas encore ton cas.

    Sinon je vais essayer avec une listeDoublementChainee de pointeur de type void.
    Commence par une liste de int. Les void*, en C++ ça ne se rencontre que quand on joue à bas niveau avec la mémoire.

  17. #17
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Citation Envoyé par Luc Hermitte
    Non.
    C++ != Java. Les références ne sont pas des variables autonomes. Ce sont des alias, des raccourcis.
    Je crois que je viens de comprendre mon erreur (après quelques heures de réflexion...). En fait, on peut faire un conteneur template qui stocke des références (je croyais que c'était là dessus que vous me corrigiez), mais on ne peut pas le déclarer comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListeDoublementChainee<Mouvement &> liste ;
    Mais nécessairement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListeDoublementChainee<Mouvement> liste ;
    Parce que "Mouvement &" n'est pas un type, c'est bien ça ?

    Remarque : je n'ai jamais fait de Java

  18. #18
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Non, c'est l'inverse. On peut très bien passer un type référence en paramètre template, mais pas le stocker.

  19. #19
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Citation Envoyé par Laurent Gomila
    Non, c'est l'inverse. On peut très bien passer un type référence en paramètre template, mais pas le stocker.
    Bon... Comme je ne comprenais toujours pas, j'ai testé.
    Voici le résultat qui fonctionne chez moi :
    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
    #include <iostream>
     
    template<typename Type>
    class MySimpleList
    {
    public:
        struct Element
        {
            Element(Type & ref):Ref(ref){}
            Type & Ref;
            Element * NextElement;
        };
     
        MySimpleList():FirstElement(NULL), LastElement(NULL){}
        void Add(Type & Item)
        {
            if(FirstElement==NULL)
            {
                FirstElement = LastElement = new Element(Item);
            }
            else
            {
                Element * temp;
                temp = LastElement;
                LastElement = new Element(Item);
                temp->NextElement = LastElement;
            }
        }
     
        Element * FirstElement;
        Element * LastElement;
    };
     
    class A
    {
    public:
        A(int a):
          _a(a)
        {}
     
        virtual int getNum()
        {
            return _a;
        }
     
        void setA(int a)
        {
            _a = a;
        }
     
    private:
        int _a;
    };
     
    class B : public A
    {
    public:
        B(int b):
          A(0), _b(b)
        {}
     
        virtual int getNum()
        {
            return _b;
        }
     
        void setB(int b)
        {
            _b = b;
        }
     
    private:
        int _b;
    };
     
    int main()
    {
        A MyA(5);
        B MyB(3);
        MySimpleList<A> AList;
        AList.Add(MyA);
        AList.Add(MyB);
     
        std::cout << "A MyA(5);" << std::endl;
        std::cout << "B MyB(3);" << std::endl;
        std::cout << "MySimpleList<A> AList;" << std::endl;
        std::cout << "AList.Add(MyA);" << std::endl;
        std::cout << "AList.Add(MyB);" << std::endl;
        std::cout << std::endl;
        std::cout << "=> first : " << AList.FirstElement->Ref.getNum() << ", last " << AList.LastElement->Ref.getNum() << std::endl;
     
        MyA.setA(10);
        MyB.setB(40);
     
        std::cout << std::endl;
        std::cout << "MyA.setA(10);" << std::endl;
        std::cout << "MyB.setB(40);" << std::endl;
        std::cout << std::endl;
        std::cout << "=> first : " << AList.FirstElement->Ref.getNum() << ", last " << AList.LastElement->Ref.getNum() << std::endl;
     
        return EXIT_SUCCESS;
    }
    Je ne suis pas très à l'aise avec les templates, donc il est fort possible que je me sois planté. Mais a priori, ce code fonctionne, et je stocke bien des références !

  20. #20
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 308
    Par défaut
    Effectivement. Seulement, c'est un conteneur de références (autant lui donner u nom plus parlant) : une vue vers autre chose. Si la donnée que tu références meurt, alors tu stockeras un lien vers une donnée invalide qui n'existe plus.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Une erreur 233 de ms sql server
    Par Hokage dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 05/10/2009, 18h40
  2. Réponses: 2
    Dernier message: 05/10/2004, 23h43

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