begin process at 2008 07 06 16:41:58
1 205 660 membres
227 nouveaux aujourd'hui
14 119 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

POINTEURS DE FONCTION DANS DES STRUCTURES


Information sur la source

Catégorie :Astuces Niveau : Débutant Date de création : 04/04/2005 Date de mise à jour : 05/04/2005 23:35:14 Vu : 4 018

Note :
6 / 10 - par 1 personne
6,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (8)
Ajouter un commentaire et/ou une note


Description

Ce code montre comment stocker vos fonctions dans une structure et cmt les utiliser par la suite...

Source

  • #include <stdlib.h>
  • #include <unistd.h>
  • typedef struct compteur {
  • int nb;
  • void (*increment)(struct compteur *this);
  • void (*decrement)(struct compteur *this);
  • int (*getValue)(struct compteur *this);
  • void (*setValue)(struct compteur *this, int n);
  • void (*free)(struct compteur *this);
  • } compteur;
  • /* définition des différentes méthodes */
  • void __compteur__increment(compteur *this){
  • this->nb++;
  • }
  • void __compteur__decrement(compteur *this){
  • this->nb--;
  • }
  • int __compteur__getValue(compteur *this){
  • return this->nb;
  • }
  • void __compteur__setValue(compteur *this, int n){
  • this->nb = n;
  • }
  • /* fin des méthodes générales */
  • /* méthodes particulières */
  • // destructeur
  • void __compteur__free(compteur *this){
  • free(this); // libération
  • }
  • // constructeur
  • compteur *Compteur() {
  • compteur *n = malloc(sizeof(compteur)); // allocation
  • n->nb = 0;
  • // set des fonctions
  • n->increment = __compteur__increment;
  • n->decrement = __compteur__decrement;
  • n->getValue = __compteur__getValue;
  • n->setValue = __compteur__setValue;
  • n->free = __compteur__free;
  • return n;
  • }
  • /* fin méthodes particulières */
  • int main(void){
  • // création
  • compteur *c = Compteur();
  • // traitement
  • c->setValue(c,20);
  • c->increment(c);
  • c->increment(c);
  • // affichage
  • printf("%d\n",c->getValue(c));
  • // libération
  • c->free(c);
  • }
#include <stdlib.h>
#include <unistd.h>


typedef struct compteur {
	int nb;

	void (*increment)(struct compteur *this);
	void (*decrement)(struct compteur *this);

	int (*getValue)(struct compteur *this);
	void (*setValue)(struct compteur *this, int n);

	void (*free)(struct compteur *this);
} compteur;


/* définition des différentes méthodes */
void __compteur__increment(compteur *this){
	this->nb++;
}

void __compteur__decrement(compteur *this){
	this->nb--;
}

int __compteur__getValue(compteur *this){
	return this->nb;
}

void __compteur__setValue(compteur *this, int n){
	this->nb = n;
}

/* fin des méthodes  générales */

/* méthodes particulières */

	// destructeur
	void __compteur__free(compteur *this){
		free(this); // libération
	}

	// constructeur
	compteur *Compteur() {
		compteur *n = malloc(sizeof(compteur)); // allocation

		n->nb = 0;

		// set des fonctions
		n->increment = __compteur__increment;
		n->decrement = __compteur__decrement;
		n->getValue = __compteur__getValue;
		n->setValue = __compteur__setValue;
		n->free = __compteur__free;


		return n;
	}
/* fin méthodes particulières */

int main(void){
	// création
	compteur *c = Compteur();

	// traitement
	c->setValue(c,20);
	c->increment(c);
	c->increment(c);

	// affichage
	printf("%d\n",c->getValue(c)); 

	// libération
	c->free(c);
}

Conclusion

Voila, ce code doit donner 22 (20+1+1).
Réalisé pour Jingle
05 avril 2005 19:36:55 :
05 avril 2005 23:35:14 :
Mise à jour suite aux commentaires...
  • signaler à un administrateur
    Commentaire de NitRic le 05/04/2005 03:45:55

    Note:

        typedef double (*__function)( double );
        __function MaFonction;

        (*MaFonction)( une_valeur ); /* fonctionnel */
        MaFonction( une_valeur ); /* fonctionnel */

    Pour appeller la fonction, le (*...) n'est pas obligatoire, ou plutôt, n'est _plus_ obligatoire ...


    Donc  ` tab[i].test( tab[i].nb ); ` suffit ...




    ~(.:: NitRic ::.)~

  • signaler à un administrateur
    Commentaire de Taranael le 05/04/2005 11:03:22

    Le code a l'air correct mais pourquoi mettre niveau Initié ?

  • signaler à un administrateur
    Commentaire de gilids le 05/04/2005 12:10:58

    Tu sais que tu es en train de réinventer la notion d'objet ? ;-)

  • signaler à un administrateur
    Commentaire de NitRic le 05/04/2005 13:07:33

    `réinventer la notion d'objet` ... et bien ... sans commentaire ...




    ~(.:: NitRic ::.)~

  • signaler à un administrateur
    Commentaire de Arnaud16022 le 05/04/2005 14:25:18

    Lol tu m'étonnes, ce code est bien pour savoir comment ca marche mais de la a se mettre en Initié ya un gouffre
    autre chose:
    (*tab[i].test)(tab[i].nb)
    heu...
    c'est correct mais chiant, le C++ a crée une nouvelle notation (heu nouvelle, elle a bien 15 ans hein)
    tab[i]->test(tab[i].nb)
    c'est plus compréhensible comme ca non?
    ++
    ad

  • signaler à un administrateur
    Commentaire de gilids le 05/04/2005 14:50:01

    Nitric, c'est dommage que tu ne fasses pas de commentaire...

    Je le précise au cas où, il ne s'agissait pas d'une critique.

    Je trouve qu'il s'agit d'une sorte de pas intermédiaire entre le C et le C++. Mettre en commun des variables et les fonctions qui les manipulent constitue bien un des premiers objectifs de la POO.

    Exemple :
    typedef struct Nombre
    {
    int nb;
    void (*Incrementer)(Nombre *this);
    }

    void IncrementerNombre(Nombre *this)
    {
    this->nb++;
    }
    void IncrementerNombrePair(Nombre *this)
    {
    this->nb += 2;
    }

    Ca ressemble beaucoup à :
    class Nombre
    {
    int nb;
    void Incrementer () virtual { this->nb++; }
    }
    class NombrePair : public Nombre
    {
    void Incrementer() virtual { this->nb += 2; }
    }


    D'ailleurs, le mécanisme utilisé pour les fonctions virtuelles en C++ est le même : une table de pointeurs appartenant à la zone mémoire contenant les données membres...

  • signaler à un administrateur
    Commentaire de Cyrille2 le 05/04/2005 23:32:04 administrateur CS

    Bjr!

    tout d'abord, merci pour vos commentaires.

    Je viens de rectifier le niveau de ce code, j'y suis peut-etre allé un peu vite... le voici donc débutant !

    Pour ce qui est de la '->', il est imposible ici de l'utiliser, cette notation étant réservé aux pointeurs sur structures et non aux pointeurs dans les structures.

    Enfin, suite à vos remarques sur la POO ... j'ai décidé de m'amuser un peu alors voici le résultat ...
    en revanche ... je n'ai pas trouvé de solution pour le this ...  car il est vrai que la cela peut paraitre étrange de faire c->methode(c); ... c vrai que c un peu inutile mais, c t juste pour me rapprocher de la POO!

    voili

  • signaler à un administrateur
    Commentaire de NitRic le 06/04/2005 02:37:52

    Cyrille2, non ce n'est pas inutile, tu pourrais, par exemple, avoir ce genre de chose:

    typedef struct _Module
    {
        type (*open)( ... );
        type (*read)( ... );
        type (*write)( ... );
        type (*close)( ... );
    }Module;


    et ensuite, pouvoir charger différents modules sans code/fichiers/... supplémentaires:

    Module mod;
    modlog_01_load( &mod );

    mod.open( ... );
    mod.close( ... );
    ...
    modlog_01_unload( &mod );
    modlog_02_load( &mod );

    mod.open( ... );
    ...


    tu pourrais avoir plusieurs modules pour gérer des fichiers jounaux par exemple et pouvoir utiliser celui que tu veux sans code supplémentaire ... ce n'est qu'un exemple ...

    Mais bref, ce n'est _pas_ inutile ...

    gilids,  c'était surtout le mot `réinventer`, c'était un peu trop non? Il n'a rien `réinventé` ici et ce n'est pas du OO, ca lui ressemble d'une certaine facon oui mais sans plus ...

    Arnaud16022, depuis le `C99 je crois`, le (*...) est devenu optionnel en C aussi, `optionnel` car on peu encore utiliser cette `notation` ...

    Au fait Cyrille2, faire de la `pseudo-OO` en C c'est vraiment `le bordel` et très laid alors continue dans cette voie, c'est beaucoup mieux ainsi :}



    ~(.:: NitRic ::.)~

Ajouter un commentaire

Pub



Appels d'offres

Plugin Dialer outlook
Budget : 2 000€
Travail graphique- ill...
Budget : 1 000€
creation de marque et ...
Budget : 1 000€

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Boutique

Boutique de goodies CodeS-SourceS