Définir, déclarer et utilser un simple patron de classe

Contenu du snippet

Ce code propose 2 fichiers entête et 1 fichier source contenant le main et une fonction amie spécialisée.

- l'entête "defpile.h" contient la définition du patron de classe Pile et la définition des ses fonctions membres
- l'entête "decpile.h" contient les déclarations de prototypes
- le fichier source permet d'utiliser les fonctionnalités proposées du patron Pile<>

Le patron Pile<> permet d'instancier des "piles" (tableaux) d'éléments de type variable (int, double ect...) et de les manipuler. Ce petit code à pour but de définir ce qu'est un patron de classe et comment l'utiliser dans d'autres sources CPP en appliquant le mécanisme de précompilation (définition-->déclaration-->utilisation).

Source / Exemple :


/*

  • TITRE : defpile.h
  • AUTEUR : popi0016
  • VERSION : V 1.01
Définition du patron de la classe "Pile" qui modèlise un tableau pouvant recevoir différents types de variables et être manipulé par les fonctions membres de cette classe.
  • /
//--------------------------------------------------------------------------- /* Teste si l'identificateur "DEFPILE_H" n'est pas défini afin de le définir une seule fois ce qui évite les inclusions multiples de cet entête. */ #ifndef DEFPILE_H #define DEFPILE_H //--------------------------------------------------------------------------- /* Inclut l'entête de gestion du flux des ENTREES/SORTIES et utilise les symboles définis dans l'espace de nommage standard "std". */ #include <iostream> using namespace std; //--------------------------------------------------------------------------- /* Définition du patron "Pile<T>". */ template <class T> class Pile { /* attributs privés */ int n_elem; // nombre d'éléments T *adresse; // adresse de ces éléments /* membres publics */ public : /* fonctions en ligne (représentant la forme canonique d'une classe). */ inline Pile(); // constructeur I inline Pile(int, T *); // constructeur II inline Pile(const Pile &); // constructeur de recopie III inline Pile & operator =(const Pile &); // opérateur d'affectation (=) inline ~Pile(); // destructeur /* méthodes classiques */ void affiche(); // affiche en colone /* fonction spécialisée aux caractères */ friend void affiche(Pile<char>); // affiche en ligne /* surdéfinition des opérateurs */ Pile operator +(const Pile &); // concaténation des "tableaux" T operator [](int); // retourne l'indice du "tableau" bool operator ==(const Pile &); // teste si 2 "tableaus" sont identiques }; /* La liste des fonctions peut être complètée à souhait... */ //--------------------------------------------------------------------------- /* Définition du constructeur I sans arguments qui crée un tableau vide sans adresse. */ template <class T> inline Pile<T> :: Pile() { n_elem = 0; // zéro éléments adresse = NULL; // adresse : NULL } /* Définition du constructeur II avec 2 arguments qui crée un tableau de taille "n" et recopie les éléments du deuxième argument. */ template <class T> inline Pile<T> :: Pile(int n, T *adr) { adresse = new T[n_elem=n]; for(int i=0; i<n_elem; i++) adresse[i] = adr[i]; } /* Définition du constructeur III de recopie, pour les passages en argument ou les retours d'objets "Pile<T>". */ template <class T> inline Pile<T> :: Pile(const Pile &p) { adresse = new T[n_elem=p.n_elem]; // alloue la copie for(int i=0; i<n_elem; i++) adresse[i] = p.adresse[i]; // initialise la copie } /* Définition de l'opérateur d'affectation (=) qui permet d'affecter un objet "Pile<T>" dans un autre objet de même type. */ template <class T> inline Pile<T> & Pile<T> :: operator =(const Pile &p) { if(&p != this) // si l'objet n'est pas lui-même ... { delete [] adresse; // évite de suppr. 2 fois la même adr. adresse = new T[n_elem=p.n_elem]; for(int i=0; i<n_elem; i++) adresse[i] = p.adresse[i]; } return *this; // les atributs sont affectés } /* Définition du destructeur. */ template <class T> inline Pile<T> :: ~Pile() { delete [] adresse; // supprime de l'espace dynamique l'adresse } /* Affiche les éléments en colonne. */ template <class T> void Pile<T> :: affiche() { for(int i=0; i<n_elem; i++) cout << adresse[i] << endl; cout << endl; } /* Surdéfinition de l'opérateur de concaténation (+) qui ajoute un "tableau" à la suite d'un autre "tableau". */ template <class T> Pile<T> Pile<T> :: operator +(const Pile &p) { Pile<T> res; // résultat de la concaténation /* prépare un espace dynamique de la taille des 2 tableaux à ajouter */ res.adresse = new T[res.n_elem=n_elem+p.n_elem]; /* copie le 1er tableau */ for(int i=0; i<n_elem; i++) res.adresse[i] = adresse[i]; /* copie le 2emme tableau à la suite */ for(int i=0; i<p.n_elem; i++) res.adresse[i+n_elem] = p.adresse[i]; return res; // retourne le résultat } /* Surdéfinition de l'opérateur [] qui retourne l'indice ciblé par l'argument */ template <class T> T Pile<T> :: operator [](int i) { if(i <= n_elem) return adresse[i]; else return T(-1); // débordement } /* Surdéfinition de l'opérateur d'identité d'objets "Pile<>" (==). */ template <class T> bool Pile<T> :: operator ==(const Pile &p) { int tmp = 0; /* choisit la taille la plus grande */ if(n_elem >= p.n_elem) tmp = n_elem; else tmp = p.n_elem; /* teste l'identité de chaque élément */ for(int i=0; i<tmp; i++) if(adresse[i] != p.adresse[i]) return false; return true; } //--------------------------------------------------------------------------- #endif // fin du test de l'identificateur "DEFPILE_H" //--------------------------------------------------------------------------- /*
  • TITRE : decpile.h
  • AUTEUR : popi 0016
  • VERSION : V 1.01
Déclaration seule du patron "Pile<>" qui permet d'utiliser celui_ci dans une autre source "cpp".
  • /
//--------------------------------------------------------------------------- /* Teste si l'identificateur "DECPILE_H" n'est pas défini afin de le définir une seule fois ce qui évite les inclusions multiples de cet entête. */ #ifndef DECPILE_H #define DECPILE_H #include "defpile.h" // inclut la définition template <class T> Pile; // déclaration void affiche(Pile<char>); //--------------------------------------------------------------------------- #endif // fin du test de l'identificateur "DECPILE_H" //--------------------------------------------------------------------------- /*
  • TITRE : main_pile.cpp
  • AUTEUR : popi0016
  • VERSION : V 1.01
Programme principale permettant d'utiliser le patron "Pile<>".
  • /
//--------------------------------------------------------------------------- #include "decpile.h" // inclut la déclaration //--------------------------------------------------------------------------- int main() // DEBUT main() { int tab_int[10] = {1,2,3,4,5,6,7,8,9,10}; // tableau d'entiers double tab_double[4] = {1.2,3.6,4.9,7.5}; // tableaux de réels char str1[] = "coucou"; // chaîne constante char str2[] = " a tous"; // chaîne constante Pile<char> pc; // pile vide Pile<int> pi1(10, tab_int); // initialisée avec le tab d'entiers Pile<double> pd1(4, tab_double); // initialisée avec le tab de doubles Pile<char> pc1(6, str1); // initialisée avec la chaîne constante Pile<char> pc2(7, str2); // initialisée avec la chaîne constante pi1.affiche(); // fonction membre pd1.affiche(); // fonction membre affiche(pc1); // fonction amie spécialisée affiche(pc2); // fonction amie spécialisée cout << pi1[1] << endl << endl; // 2emme élément des entiers cout << pd1[2] << endl << endl; // 3emme élément des doubles pc = pc1 + pc2; // concaténation de chaînes affiche(pc); // fonction amie spécialisée cout << boolalpha << (pi1 == pi1) << endl << endl; cout << boolalpha << (pc == pc1) << endl << endl; return 0; } // FIN main() //--------------------------------------------------------------------------- /* Affiche les éléments en ligne, fonction amie spécialisée. */ void affiche(Pile<char> p) { for(int i=0; i<p.n_elem; i++) cout << p.adresse[i]; cout << endl << endl; } //---------------------------------------------------------------------------

Conclusion :


En déposant ce code je remercie modestement les membres de ce site qui m'ont aidé et en espérant que ceci aidera quelqu'un : )

A voir également

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.