UNE PILE TEMPLATES + SURCHARGE OPERATEUR

mickbad Messages postés 71 Date d'inscription mercredi 17 juillet 2002 Statut Membre Dernière intervention 20 avril 2008 - 7 févr. 2006 à 15:57
e52guill Messages postés 6 Date d'inscription vendredi 25 avril 2003 Statut Membre Dernière intervention 10 mai 2006 - 10 mai 2006 à 20:44
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/35936-une-pile-templates-surcharge-operateur

e52guill Messages postés 6 Date d'inscription vendredi 25 avril 2003 Statut Membre Dernière intervention 10 mai 2006
10 mai 2006 à 20:44
Bonjour

On est bien d'accord sur les termes définitions et déclarations, on déclare dans le h et on définit dans le cpp. En revanche et comme je n'ai pas les sources (pas membre), je me posais des questions à propos de cette règle lorsque l'on utilise des templates: à savoir que dans un patron de classe on réalise la définition des fonctions membres dans le header.

Peux tu me confirmer celà ou au contraire me dire si il est possible de définir les fonctions membres d'un patron de classe dans le cpp (comme on le fait d'habitude avec des classe qui ne sont pas préfixé de template<typename T>).
mickbad Messages postés 71 Date d'inscription mercredi 17 juillet 2002 Statut Membre Dernière intervention 20 avril 2008
10 mai 2006 à 15:39
Salut,

Avant de te répondre, connais-tu la différence entre déclarer et définir une fonction ? Si oui tant mieux mais au cas où :
- Déclaration ou prototype (même ça s'applique plus ailleurs) est le moyen de dire au compilateur qu'une fonction existe et qu'elle peut être appelée
- Définition est juste le contenu de la fonction (le compilateur va dans cette "définition" lors d'un appel)

Le .h du terme header devrait contenir toutes les déclarations ou macros, prototypes, structures (struct, enum, union, class ...) d'un programme. J'utilise le conditionnel car c'est une bonne façon de faire qui existe depuis le début du C (même avant).

Alors oui, les déclarations des fonctions d'une classe (appelées aussi méthodes) doivent se faire dans le même fichier où il y a les termes 'class gnagna { ... }; '
c'est logique car il s'agit de la "déclaration" de la classe.

Bien sûr (en terme objet), tu peux "définir" des méthodes de classe dans le .h si elles sont de type inline (à peu près équivalent aux macros).

Pourquoi faire un .h alors qu'on peut tout faire dans un CPP ?
réponse : la réutilisation pour plusieurs parties de code.
Quand ton programme possède plusieurs fichier .cpp, il est compilé par module le plus souvent donc chaque .cpp donne un .obj ou .o (dépend où on se trouve :)), ensuite "on" assemble les .obj/.o pour un exécutable

En plus clair ton programme comporte 2 fichier .cpp avec le même .h (déclaration d'une classe). Si en fait ta déclaration de classe se faisait dans chaque .cpp, la compilation se passera bien (car modulaire) mais lors de l'assemblage le 2e .obj généré provequera une erreur : la classe existe déjà !!

m'enfin juste en aparté :)


Donc tu as raison, les déclarations dans le .h et les définitions (sauf macros ou inline) dans le .cpp

.Mick.
e52guill Messages postés 6 Date d'inscription vendredi 25 avril 2003 Statut Membre Dernière intervention 10 mai 2006
10 mai 2006 à 11:53
Bonjour Mickbad

En lisant ton commentaire me vient une réaction quant à la séparation de la déclaration du fichier de la définition (l'eternel fracture .h .cpp). Lorsque l'on crée un patron de classe, je pensais que la déclaration des fonctions de la classe devait se faire dans le même fichier. Est ce que je me trompe?
mickbad Messages postés 71 Date d'inscription mercredi 17 juillet 2002 Statut Membre Dernière intervention 20 avril 2008
7 févr. 2006 à 16:06
autant pour moi avec
int operator ++()
int operator --()

Le compilateur ne dit rien car ya rien de faux là dedans !

Vu que c'est assez rare que j'utilise ces surcharges (++, --), j'en oublie un peu les fondamentaux ;)

héhé!

.Mick.
mickbad Messages postés 71 Date d'inscription mercredi 17 juillet 2002 Statut Membre Dernière intervention 20 avril 2008
7 févr. 2006 à 15:57
Salut,

Je reste dubitatif sur ces fonctions dans ta classe:
int operator ++()
int operator --()

1°) la surcharge des opérateurs ++ et -- ne se déclare *généralement* pas comme ça même si le compilateur ne te crie pas dessus (c'est le cas chez moi avec cygwin/gcc). La déclaration se ferait plutôt comme suit (*mais* juste un exemple)
T& operator++ (T& val)

2°) dans le main l'utilisation de ++ serait alors fausse:
--> Stack <float> ti(40);
--> [...]
--> ti++; /* ERREUR : => tt.operator++(1) not found! */

3°) dans le contenu de ces fonctions
--> //renvoie 1 si pile pleine sinon 0
--> return (count==size_max) ?(1):(0);
mouaip, tu veux faire quoi au juste avec ton ++ et ton -- ?

Voilà pour la partie des surcharges.

Au niveau du reste du code : attention une fuite de mémoire est détectée => tu alloues tab dans ton constructeur mais aucune trace de sa désallocation (pas de destructeur aussi tiens).
Ok pour des types simples (int, float), le compilateur va peut être créer un "bon" destructeur pour supprimer ton "tab" mais imagine que tu utilises à la place une structure de données complexe ... oulala!
Rien ne vaut de le faire soi-même => JAMAIS faire confiance au compilateur!!

En restant sur le même sujet, dans le main, tu vas crée une pile de 1 élément. Le programme peut (dans l'état) fonctionner normalement *mais* dans un plus grand programme, tu vas avoir de sérieux problèmes. En effet, lorsque ta pile sera rempli (1 élément) et lors de l'insertion d'un nouvel élément, tu écriras *n'importe où* dans la zone mémoire au risque d'écraser tes autres allocations!
Suis-je clair ?

Pour résumer tu peux avoir ce cas là (en gros, hein?)
(mémoire <=> case à remplir)
char* s alloué et rempli => |t|e|s|t|\0| (5 cases)
Stack <float> ti(1) idem => |1.0| (1 case)

ti << 99; (comprends pas trop comment tu veux faire fonctionner ça mais admet-on)

Au niveau mémoire, la valeur 99 ne vas pas forcément s'écrire comme suite à 1.0 mais peut être dans ta chaîne: par exemple s => |t|e|99.0|t|\0|

fun, non ?


Enfin, ton exit(-1) dans ton constructeur .. mouaip!
=> une erreur d'écriture de code et paf, te voilà jeté du programme, là pour le coup pas fun :)!


Bon, l'idée est bonne mais tu as du boulot !
pense aussi à séparer la partie déclaration de ta classe et définition des fonctions membres (2 fichiers :)

.Mick.
Rejoignez-nous