IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

méthodes statiques privées


Sujet :

C++

  1. #1
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut méthodes statiques privées
    Bonjour,

    dans une annale d'épreuve d'info, je suis tombé sur la déclaration d'une classe en C++ dans laquelle se trouvaient des méthodes statiques privées. Je pense qu'il s'agit d'une erreur du sujet, ou alors une subtilité m'échappe.

    Pouvez-vous confirmer?

    Merci.

  2. #2
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Bonjour,

    Ce n'est pas très courant en effet, mais pourquoi pas après tout ?

    On pourrait imaginer une fonction membre statique publique assez complexe qui appellerait en fait quelques fonctions helper qui seraient des fonctions membres statiques privées. Le but serait d'éviter que ces sous-fonctions soient appelées directement hors de la classe.

  3. #3
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    J'ai peut être un exemple :

    Tu as une classe A et une classe B.

    La classe B permet l'accès à une table d'une base de données.

    Toutes les instances de la classe A ont besoin d'une instance de la classe B pour lire/écrire dans cette table.

    Mais il est inutile d'avoir une instance de la classe B pour chaque instance de la classe A, une seule instance de B suffit.

    On va donc faire un attribut de classe (= attribut statique) dans A comprenant un pointeur sur une instance de B (on ne peut pas le faire dans B car d'autres classes auraient peut être besoin d'autres instances).
    Dès lors on peut décider de créer une méthode statique getInstanceB() qui créé une instance de B si l'attribut de classe est à NULL, qui met son adresse dans l'attribut de classe puis retourne l'adresse.

    On peut même mettre en place un compteur pour savoir combien de classes utilisent B (pour éventuellement la détruire quand aucune classe l'utilise). Ou s'en servir pour mettre en place des Mutex si on veut qu'une seule instance de A puisse accèder à l'instance de B à la fois.


    A partir de là, l'instance de B ne doit être utilisée que par des instances de A. On ne veut pas que les autres classes puissent écrire dans la table ou incrémente/décrément le compteur ou prenne le Mutex.

    Dans ce cas là, l'attribut et la méthode statiques seront privé.

    En gros :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    //.h
    class B;
     
    class A
    {
            private static B * table;
            private static B * getInstance();
            A();
    };
     
    // .cpp
     
    private static A::B * table = NULL; //je ne suis pas sûr de la syntaxe
    private static B * A::getInstance()
    {
             if(!table)
                    table = new B('localhost', 'password', 'login', 'table');
             //éventuellement incrémentation d'un compteur statique
             //éventuellement un mutex (statique)
             return table;
    }
     
     
    //éventuellement :
    private static void A::fermerTable()
    {
           //décrémentation d'un compteur statique
                //si le compteur est à 0, on détruit l'instance de B et on met table à NULL
           //ou on peut rendre un jeton (Mutex)
    }

    Mais si on réfléchit bien, on pourrait utiliser un méthode private pour faire ceci.

    Mais A à un amis C, et C a la possibilité d'écrire lui-même dans la table.
    C doit pouvoir écrire dans la table sans qu'une instance de A existe, on a donc besoin d'une méthode statique privée.

  4. #4
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut
    On pourrait imaginer une fonction membre statique publique assez complexe qui appellerait en fait quelques fonctions helper qui seraient des fonctions membres statiques privées. Le but serait d'éviter que ces sous-fonctions soient appelées directement hors de la classe.
    Ca fonctionnerait aussi bien en mettant les fonction helper privée sans être statiques il me semble.

    Mais A à un amis C, et C a la possibilité d'écrire lui-même dans la table.
    C doit pouvoir écrire dans la table sans qu'une instance de A existe, on a donc besoin d'une méthode statique privée.
    Merci pour l'exemple. Il fallait y penser. Il semble que ça puisse être le cas. Voici le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    1. #ifndef __SOCKET_H__
    2. #define __SOCKET_H__
    3. #include <WinSock2.h>
    4. #include <string>
    5. typedef std::string String;
    // Superclasse
    6. class Socket
    7. {
    8.   public:
    9.    enum TYPE { STREAM=SOCK_STREAM, DATAGRAM=SOCK_DGRAM };
    10.   Socket(const Socket&);
    11.   virtual ~CSocket();
    12.   Socket& operator=(const Socket& sock);
    13.   String receiveLine();
    14.   String receiveBytes();
    15.   int receive(void* buf, unsigned size);
    16.   void close();
    17.   void sendLine (String s);
    18.   void sendBytes(const String& s);
    19.   void sendBytes(const unsigned char* buff);
    20.   void send (const void* buff, unsigned n);
    21.  protected:
    22.   friend class SocketServer;
    23.   Socket(SOCKET s);
    24.   Socket();
    25.   SOCKET s_; // le socket de la winsock
    26.   int* refCounter_;
    27.  private:
    28.   static void start(); // initialise la librairie des sockets
    29.   static void end(); // termine l'utilisation des winsock
    30   static int nofSockets_; // nombre de sockets
    31. };
    32. #endif //__SOCKET_H__

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Je ne sais pas exactement ce que fait tes fonctions mais je suppose que :



    static void start();si nofSockets_ est à 0 initialise la bibliothèque puis l'incrémente (il faudrait regarder ce que fais exactement ta fonction.



    static void end();Décrémente nofSockets_ et s'il est à 0 termine l'utilisation des winsock.


    Ces méthodes doivent pouvoir être utilisé par la classe Socket ET la classe ServerSocket sans qu'une instance de la classe Socket existe.

    C'est une espèce de "singleton privé".

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    En fait, une fonction statique est simplement une fonction qui ne dépend d'aucune instance de la classe pour être appelée.

    Alors, imaginons que tu aies une fonction publique et statique complexe (comprends : qui se retrouve à avoir plusieurs responsabilités distinctes pour arriver à produire le service qu'on en attend):

    En vertu du principe de la responsabilité unique, tu vas essayer de factoriser les différentes responsabilités dans une série d'autres fonctions, qui ne dépendent pas forcément d'une instance particulière de ta classe (et qui peuvent donc être statiques).

    Mais, Demeter aidant, tu peux parfaitement estimer qu'une (ou plusieurs) de ces fonctions n'ont aucune raison d'être exposées, et tu décideras donc sans doute de les rendre privées.

    Il n'y a donc absolument rien de choquant à se retrouver avec des fonctions statiques privées, d'autant plus que l'on pourrait également envisager le fait de placer une amitié bien réfléchie pour, malgré tout, permettre à une seule et unique classe d'accéder à ces fonctions
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut
    Je ne sais pas exactement ce que fait tes fonctions mais je suppose que :
    Voilà tout ce que l'on sait sur cette partie du problème, ainsi que la question posée:
    La librairie winsock impose les contraintes suivantes
    La librairie ne doit être initialisée qu’une seule fois dans un même processus
    Lorsque les sockets ne sont plus utilisés dans un processus, la fonction WSACleanup doit être appelée
    Donner le pseudo code du/des algorithme(s) à mettre en place pour respecter ces contraintes lors :
    1. de la création d’un objet de la classe Socket
    2. de la destruction d’un objet de la classe
    Préciser dans quelle(s) fonction(s) sont exécutés ces algorithmes
    Autant je comprends la présence de nofSockets_ déclaré en membre statique privé, autant je ne comprends toujours pas comment va se faire l'appel à start() et stop().

  8. #8
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut
    Alors, imaginons que tu aies une fonction publique et statique complexe (comprends : qui se retrouve à avoir plusieurs responsabilités distinctes pour arriver à produire le service qu'on en attend):

    En vertu du principe de la responsabilité unique, tu vas essayer de factoriser les différentes responsabilités dans une série d'autres fonctions, qui ne dépendent pas forcément d'une instance particulière de ta classe (et qui peuvent donc être statiques).
    Oui, je comprends bien qu'elles peuvent être statiques, mais comme ce n'est pas obligatoire, pourquoi les qualifier de statiques?

    Merci en tout cas de vos interventions

  9. #9
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par jackk Voir le message
    Oui, je comprends bien qu'elles peuvent être statiques, mais comme ce n'est pas obligatoire, pourquoi les qualifier de statiques?

    Merci en tout cas de vos interventions
    Parce qu'elles sont peut etre elles-même appelées depuis une fonction statique et donc indépendante de toute instance de la classe, tout simplement
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Parce qu'elles sont peut etre elles-même appelées depuis une fonction statique et donc indépendante de toute instance de la classe, tout simplement
    Et ça ne fonctionnerait pas si elles n'étaient pas statiques. Une fonction statique peut bien appeler une fonction non statique de la même classe.

    A+

  11. #11
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Certes, une fonction statique peut appeler une méthode non statique de la classe si et seulement si la fonction statique a un pointeur ou une référence (passé en paramètre ou en attribut statique) d'une instance de la classe.

    Il faut donc qu'il existe au moins une instance de la classe pour utiliser la méthode non-statique.

    Or SocketServer doit pouvoir ouvrir un socket sans qu'une instance de Socket existe forcément.

  12. #12
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par jackk Voir le message
    Et ça ne fonctionnerait pas si elles n'étaient pas statiques. Une fonction statique peut bien appeler une fonction non statique de la même classe.
    Non, certainement pas. Une fonction statique n'est pas liée à une instance de la classe, si une fonction statique était capable d’appeler directement une fonction non statique, quelle instance devrait-elle choisir !?

    En clair, que ferait le code suivant ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct C
    {
       int i ;
       void A(){ i = 2}
       void StaticA(){A();}
    }
     
    int main()
    {
       C c1, c2, c3;
       C::StaticA();
    }
    Une fois appelé StaticA(), quelles seraient les données membres "i" mises à jours ? Celles de c1, de c2 ou de c3 ? Aucune ? Tous les i de toutes les instances de C dans tous le programme ?

  13. #13
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2004
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juin 2004
    Messages : 539
    Par défaut
    Parfait!

    Merci à vous.

  14. #14
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Une derniere note:

    dans le cas ou on penserai a une fonction statique privee, si la classe n'est pas definie entierement dans un header, j'ai tendance a plutot utiliser une fonction dans un namespace anonyme dans le cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    // header
    class Machin
    {
    public:
     
         void do_it();
     
    };
     
     
    // cpp
     
    namespace 
    {
     
         int computation( int k )
         { 
                //...
         }
     
    } 
     
     
    void Machin::do_it()
    {
         int u = 42;
         //.... 
         auto z = computation(u);
     
         //....
    }
    Pourquoi?

    1. (si j'ai bien compris) le namespace anonyme garanti que tout ce qu'il y q dedans n'est pas visible a l'exterieur de l'unite de compilation (le cpp), du coup c'est encore plus isole que si c'etait un membre prive, puisqu'il n'apparait pas dans le header et ne genere pas de symbole utilise au link.
    2. je peu changer la signature de tout ce qui n'est visible que dans le cpp autant que je veux sans impacter le reste du code, meme sans toucher le header, ce qui est bien moins de travail que si c'etais des membres prives ou pas.

    Le seul souci c'est que cela ne s'applique que aux classes ou l'on peut isoler la definition, donc pas les templates, et pas les fonctions qui doivent etre accessible par les classes enfant.
    dans ces dernier cas, la fonction statique prive semble une bonne solution pour eviter de rendre la fonction accessible aussi a l'exterieur, tout en exposant tout son code.

  15. #15
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Le seul souci c'est que cela ne s'applique que aux classes ou l'on peut isoler la definition, donc pas les templates, et pas les fonctions qui doivent etre accessible par les classes enfant.
    Si la méthode doit être accessible via une classe enfant, ce ne sera plus une méthode privée mais plutôt une méthode protected (?)

    Tu ne voulais pas plutôt dire accessibles aux classes amies?

  16. #16
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Si la méthode doit être accessible via une classe enfant, ce ne sera plus une méthode privée mais plutôt une méthode protected (?)

    Tu ne voulais pas plutôt dire accessibles aux classes amies?
    Les deux!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Objet] Accès à propriété privée depuis méthode statique
    Par Invité dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 20/09/2011, 13h39
  2. Dynamic link et Méthode statique
    Par Higestromm dans le forum C++
    Réponses: 2
    Dernier message: 19/05/2006, 22h07
  3. Pthreads, méthode statique ?
    Par tibouchou dans le forum C++
    Réponses: 4
    Dernier message: 15/03/2006, 21h51
  4. [C#] interface, méthodes statiques ?
    Par gmonta dans le forum C#
    Réponses: 6
    Dernier message: 02/12/2005, 10h27
  5. [Singleton] Différences avec méthodes statiques
    Par Franche dans le forum Design Patterns
    Réponses: 1
    Dernier message: 26/02/2003, 17h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo