Une pile templates + surcharge operateur

Soyez le premier à donner votre avis sur cette source.

Vue 6 746 fois - Téléchargée 534 fois

Description

Un code-source ss pretention, pour montrer la puissance des templates, avec qqch de simple.
En plus, j'ai surchargé les opérateurs ">>"(pop) et "<<"(push)
J'attends vos commentaires ;)

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
6
Date d'inscription
vendredi 25 avril 2003
Statut
Membre
Dernière intervention
10 mai 2006

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>).
Messages postés
71
Date d'inscription
mercredi 17 juillet 2002
Statut
Membre
Dernière intervention
20 avril 2008

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.
Messages postés
6
Date d'inscription
vendredi 25 avril 2003
Statut
Membre
Dernière intervention
10 mai 2006

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?
Messages postés
71
Date d'inscription
mercredi 17 juillet 2002
Statut
Membre
Dernière intervention
20 avril 2008

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.
Messages postés
71
Date d'inscription
mercredi 17 juillet 2002
Statut
Membre
Dernière intervention
20 avril 2008

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.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.