[c++] classe de gestion de fonctions

Soyez le premier à donner votre avis sur cette source.

Vue 5 113 fois - Téléchargée 307 fois

Description

Au départ c'était pour refaire un peut de modèles, namespaces, membres statiques et pointeurs de fonctions, mais il se trouve que ça a donné un truc de gestion utile :)

Au final c'est une petite classe nommée "Vecteur" qui peut-être est pratique pour répéter plusieurs fonctions sur des grandes séquences de nombres.

Quand on a N nombres à répéter avec X fonctions, au lieu de devoir écrire environs N x X lignes de codes, on en a plus que N + X.

Exemple avec un int*:

Au lieu de :

int* nb1 = new int (3);
int* nb2 = new int (4);
int* nb3 = new int (7);
int* nb4 = new int (15);

fonctionA (nb1)
fonctionA (nb2)
fonctionA (nb3)
fonctionA (nb4)

fonctionB (nb1)
fonctionB (nb2)
fonctionB (nb3)
fonctionB (nb4)

fonctionC (nb1)
fonctionC (nb2)
fonctionC (nb3)
fonctionC (nb4)

fonctionD (nb1)
fonctionD (nb2)
fonctionD (nb3)
fonctionD (nb4)

on a :

Vecteur <int*> vecteurNombres (4);
vecteurNombres[0] = new int (3);
vecteurNombres[1] = new int(4);
vecteurNombres[2] = new int(7);
vecteurNombres[4] = new int(15);

Vecteur <int *> vecteurFonctions;
vecteurFonctions.AddFonction(fonctionA);
vecteurFonctions.AddFonction(fonctionB);
vecteurFonctions.AddFonction(fonctionC);
vecteurFonctions.AddFonction(fonctionD);

vecteurFonctions.Executer(vecteurNombres);

De plus la méthode Executer() se surcharge et l'on peut préciser quelle fonction elle doit exécuter (par défaut toutes).
Le type rentré dans le vecteur de fonctions doit être le même que celui du vecteur de nombres.

Source / Exemple :


#include <iostream>

namespace RyFonctions
{
	const int TailleDefaut = 0;
	template <typename T>
	class Vecteur
	{
	public:

		friend  class TraitementFonctions;
		Vecteur (int Taille = TailleDefaut);
		Vecteur (const Vecteur &);
		~Vecteur ();
		Vecteur& operator= (const Vecteur &);

		T& operator[] (int Position) const;

		int GetTaille () const;

		void AddFonction  (void (*ptrFonction)(Vecteur<T >) );
		void Executer (Vecteur <T> );
		void Executer (Vecteur<T>, int);

		void Effacer ();

		static int GetNbVecteurs()
		{
			return wNombreVecteurs;
		}

	private:

		void (*wTableauFonctions[500])(Vecteur <T>);
		T*pType;
		int wTaille;

		static int wNombreVecteurs;

	};

	template <class T>
	int Vecteur<T>::wNombreVecteurs = 0;

	template <class T>
	Vecteur<T>:: ~Vecteur ()
	{
		delete[] pType;
		wNombreVecteurs--;
	}
	template <class T>
	T&
	Vecteur<T>::operator[] (int Position) const
	{
		return pType[Position];
	}

	template <class T>
	Vecteur<T>::Vecteur(int Taille):
	wTaille(Taille)
	{
		wNombreVecteurs++;
		pType = new T[Taille];
		for (int i = 0; i < Taille; i++)
		pType[i] = 0;
	}

	template <class T>
	Vecteur<T>::Vecteur(const Vecteur &rhs)
	{
		wNombreVecteurs++;
		wTaille = rhs.GetTaille();
		pType = new T[wTaille];
		for (int i = 0; i < wTaille; i++)
		pType[i] = rhs[i];
	}

	template <typename T>
	Vecteur<T>&
	Vecteur<T>::operator=(const Vecteur &rhs)
	{
		if (this == &rhs)
		return *this;
		delete [] pType;
		wTaille = rhs.GetTaille();
		for (int i = 0; i <  wTaille; i++)
		pType[i] = rhs[i];
		return *this;
	}

	template <typename T>
	int
	Vecteur<T>::GetTaille () const
	{
		return wTaille;
	}

	template <typename T>
	void
	Vecteur<T>::AddFonction  (void (*ptrFonction)(Vecteur<T >) )
	{
		wTableauFonctions[wTaille] = ptrFonction;
		wTaille ++;
	}

	template <typename T>
	void
	Vecteur<T>:: Executer (Vecteur <T> Sequence)
	{
		for (int i = 0; i < wTaille; i++)
		{
			if (wTableauFonctions[i] == 0)
			continue;

			Vecteur <T> Tr = Sequence;
			std::cout << "\n";
			wTableauFonctions[i] (Tr);

		}

	}

	template <typename T>
	void
	Vecteur<T>::Executer (Vecteur<T> Sequence, int numFonction)
	{
		if (wTableauFonctions[numFonction] == 0)
		return;

		Vecteur <T> Tr = Sequence;
		std::cout << "\n";
		wTableauFonctions[numFonction] (Tr);

	}

	template <typename T>
	void
	Vecteur<T>::Effacer ()
	{
		delete [] pType;
		for (int i = 0; i < wTaille; i++)
		wTableauFonctions[i] = 0;
		wTaille = 0;

	}

}

namespace ryf = RyFonctions;

namespace RyFonctions
{

	void fonction2Xi (Vecteur <int *> Sequence);

	void fonctionX2i (Vecteur <int* > Sequence);

	void fonctionXMod3i (Vecteur <int*> Sequence);

	void fonctionXDiv10d (Vecteur <double*> Sequence);

	void fonctionXPlus4d (Vecteur <double*> Sequence);
}

void ryf::fonction2Xi (ryf::Vecteur <int* > Sequence)
{
	for (int i = 0 ; i < Sequence.GetTaille(); i++)

  • Sequence[i] *=2;
} void ryf::fonctionX2i (ryf::Vecteur <int *> Sequence) { for (int i = 0 ; i < Sequence.GetTaille(); i++)
  • Sequence[i] *= *Sequence[i];
} void ryf::fonctionXMod3i (ryf::Vecteur <int *> Sequence) { try { for (int i = 0 ; i < Sequence.GetTaille(); i++) { if (*Sequence[i] == 0) throw "Modulo de 0 impossible";
  • Sequence[i] %= 3;
} } catch (const char *e) { std::cerr << "Une erreur est survenue : " << e << ". \n"; } catch (...) { std::cerr << "\nUne erreur dont l'origine est inconnue est survenue. \n"; } } void ryf::fonctionXDiv10d (ryf::Vecteur <double* > Sequence) { for (int i = 0; i <Sequence.GetTaille();i++)
  • Sequence[i] /= 10;
} void ryf::fonctionXPlus4d (ryf::Vecteur<double*> Sequence) { for (int i = 0; i < Sequence.GetTaille(); i++)
  • Sequence [i] += 4;
} using namespace ryf; int main() { //Exemple 1 : Execution de toutes les tâches en une seule fois std::cout << "Exemple 1 : Calcul en une fois d'une sequence de 3 integers"; Vecteur<int*> Sequence (3); Sequence[0] = new int(85); Sequence[1] = new int(55); Sequence[2] = new int(56); Vecteur<int*> vectFonctions; vectFonctions.AddFonction(fonction2Xi); vectFonctions.AddFonction(fonctionX2i); vectFonctions.AddFonction(fonctionXMod3i); vectFonctions.Executer(Sequence); for (int i =0; i < 3; i++) std::cout << "\nSequence [" << i << "] : " << *Sequence[i] << std::endl; //Exemple 2 : Affichage étape par étape de nombres de type double grâce à la surchage de Executer(). std::cout << "\n\n\nExemple 2 : Affichage etape par etape d'une sequence de 5 doubles \n\n"; Vecteur<double*>Sequence2(5); for (int i = 0; i < 5; i++) Sequence2[i] = new double( (double)i * 15 + 1); Vecteur<double*> vectFonctions2; vectFonctions2.AddFonction(fonctionXDiv10d); vectFonctions2.AddFonction(fonctionXPlus4d); std::cout << "\n\nNombre de Vecteur<double*> : " << Vecteur<double*>::GetNbVecteurs() << "\n\n"; vectFonctions2.Executer(Sequence2, 0); // Execute la fonction 0 donc XDiv10d for (int i =0; i < 5; i++) std::cout << "\nNombre : " <<( i*15 + 1) << " divise par 10 devient : = " << *Sequence2[i] << std::endl; vectFonctions2.Executer(Sequence2, 1); // Execute la fonction 1 donc XPlus4d for (int i =0; i < 5; i++) std::cout << "\npuis on ajoute 4 : " << " : " << *Sequence2[i] << std::endl; std::cout << "\n\n\n"; system ("PAUSE"); return 0; }

Conclusion :


Ça permet aussi d'appliquer plusieurs fois une série de fonction sans trop de codes, on a juste à réécrire : vecteurFonctions.Executer(vecteurNombres);

Dans l'espace nom RyFonctions j'ai mis 2-3 fonctions toutes faites, mais on peut en refaire avec comme prototype :

void saFonction (ryf::Vecteur <typeVariable> nomVariable);

Par défaut, un Vecteur peut gérer jusqu'à 500 fonctions, pour en faire plus il faut modifier la ligne :
void (*wTableauFonctions[500])(Vecteur <T>); dans la classe vecteur.

L'espace de nom est RyFonctions, mais il a un alias ryf pour faire plus court.
(Ne m'en veuillez pas pour le using namespace, c'est juste pour le test ;) )

Pour tester l'exécutable, renommez "RyFonctions.ex_" en "RyFonctions.exe".

Codes Sources

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.