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 :

Pour ou contre l'amitié entre classes [Débat]


Sujet :

C++

  1. #21
    screetch
    Invité(e)
    Par défaut
    ce que j'aurais aimé voir en C++, c'est un contrôle plus fin comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class A
    {
    public:
      A();
      ~A();
    private: //privé privé!
      int m_a;
    friend class B: //privé, sauf pour B
      int m_b;
    };
    histoire que B n'aie pas soudainement accès a toute la classe. Cela permet de définir trés précisément qui a accès a quoi

    un exemple de friend assez utile:
    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
    class Mutex
    {
        friend class ScopedMutexLock;
    private:
        void*           m_data;
    public:
        Mutex();
        ~Mutex();
    private:
        void release();
        void wait();
    };
     
    class ScopedMutexLock
    {
    private:
        Mutex&  m_mutex;
    public:
        inline ScopedMutexLock(Mutex& m) : m_mutex(m)   { m_mutex.wait(); }
        inline ~ScopedMutexLock()                       { m_mutex.release(); }
    private:
        ScopedMutexLock& operator=(const ScopedMutexLock& other);
        ScopedMutexLock(const ScopedMutexLock& other);
    };
    ainsi on ne peut pas vérouiller un mutex partout comme un cochon et oublier d'appeler release; on ne peut accéder a ces fonctions qu'a travers un objet Lock

  2. #22
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Malheureusement, si tu déclare quelque chose comme étant ami de ta classe, ce que tu déclare ami a acces à tout...

    Mais... Il faut se rappeler que l'amitié n'est ni héritée, ni transitive ni réciproque

    Au risque de complexifier ton modèle, tu peux donc parfaitement envisager de créer une classe parent supplémentaire, qui ne contient que ce à quoi tu souhaite que la classe amie aie réellement accès:
    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
    class PrivateClass
    {
    friend class FriendClass;
    public:
    protected:
        int i; // in protected accessibility so that derived class have access
               // to i without to need any getter / setter
        PrivateClass():i(153){}
    };
    class Derived : public PrivateClass
    {
    public:
        Derived():j(2){}
    private:
        int j;
    };
    class FriendClass
    {
    public:
        void changeValues(Derived & d)
        {
            std::cout<<"before change, i="<<d.i<<std::endl;
            d.i=15; // OK due to friendship with PrivateClass
         // d.j=63;  // KO: no friendship with Derived: j is inaccessible
            std::cout<<"after changes, i="<<d.i<<std::endl;
        }
    };
    [EDIT]PS: nous arrivons, peut être, dans une situation dans laquelle nous pourrions justifier le non respect de LSP dont il est question ici
    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

  3. #23
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par screetch Voir le message
    ce que j'aurais aimé voir en C++, c'est un contrôle plus fin comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class A
    {
    public:
      A();
      ~A();
    private: //privé privé!
      int m_a;
    friend class B: //privé, sauf pour B
      int m_b;
    };
    histoire que B n'aie pas soudainement accès a toute la classe. Cela permet de définir trés précisément qui a accès a quoi
    Je plussoie, ça serait quelque chose de très sympathique. On peut toutefois contourner en partie le problème en composant les objets différemment. Mais ce n'est qu'un contournement qui, bien que tout à fait légitime, n'en est pas moins limité et peu agréable.

    En fait, je pense qu'il aurait fallu au niveau de la syntaxe quelque chose de plus général, peut-être ressemblant à la capture list des lambda.

    Citation Envoyé par screetch Voir le message
    ainsi on ne peut pas vérouiller un mutex partout comme un cochon et oublier d'appeler release; on ne peut accéder a ces fonctions qu'a travers un objet Lock
    Voui et non. J'ai du mal à formaliser mon désaccord, mais je pense que c 'est plus contre-productif qu'autre chose. Au niveau de l'interface, comment implémentes-tu le try-lock? Et dans ce cas, le release (si le lock a réussi) ?
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  4. #24
    screetch
    Invité(e)
    Par défaut
    déjà j'évite le trylock donc j'avoue que le probleme c'est jamais posé pour moi
    le code multithread est deja suffisemment complexe pour ne pas rajouter des cas particuliers par dessus

    si c'est utile, un truc comme:
    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
    class ScopedMutexTryLock
    {
    private:
        Mutex&  m_mutex;
        bool m_result;
    public:
        inline ScopedMutexTryLock(Mutex& m) : m_mutex(m), m_result(m.trylock())   { }
        inline ~ScopedMutexTryLock()                       { if(m_result) m_mutex.release(); }
        operator bool() const { return m_result; }
        bool operator !() const { return !m_result; }
    };
     
    int foo()
    {
       ScopedMutexTryLock lock(m_mutex);
       if(lock)
       {
       }
    }
    c'est forcément gênant puisque le if est "optionnel" et il est possible de le confondre très facilement avec le ScopedMutexLock. Mais comme dit plus haut, je ne l'ai pas ajouté donc le problème se pose pas pour moi.


    Après pour la contre-productivité, ca se discute. Moi je dis que le couple lock/release a un coût caché qui est le temps de debugging que l'objet lock n'a pas. et j'aime bien que l'on prenne en compte le temps perdu a réparer un truc. Mais je comprends ce que tu veux dire, c'est un peu moins flexible et il se peut qu'il faille se contortionner un peu pour l'utiliser.

  5. #25
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par screetch Voir le message
    déjà j'évite le trylock donc j'avoue que le probleme c'est jamais posé pour moi
    le code multithread est deja suffisemment complexe pour ne pas rajouter des cas particuliers par dessus

    si c'est utile, un truc comme:
    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
    class ScopedMutexTryLock
    {
    private:
        Mutex&  m_mutex;
        bool m_result;
    public:
        inline ScopedMutexTryLock(Mutex& m) : m_mutex(m), m_result(m.trylock())   { }
        inline ~ScopedMutexTryLock()                       { if(m_result) m_mutex.release(); }
        operator bool() const { return m_result; }
        bool operator !() const { return !m_result; }
    };
     
    int foo()
    {
       ScopedMutexTryLock lock(m_mutex);
       if(lock)
       {
       }
    }
    c'est forcément gênant puisque le if est "optionnel" et il est possible de le confondre très facilement avec le ScopedMutexLock. Mais comme dit plus haut, je ne l'ai pas ajouté donc le problème se pose pas pour moi.


    Après pour la contre-productivité, ca se discute. Moi je dis que le couple lock/release a un coût caché qui est le temps de debugging que l'objet lock n'a pas. et j'aime bien que l'on prenne en compte le temps perdu a réparer un truc. Mais je comprends ce que tu veux dire, c'est un peu moins flexible et il se peut qu'il faille se contortionner un peu pour l'utiliser.
    Solution intéressante.

    Et remarque intéressante aussi. C'est vrai que le lock/unlock explicite peut provoquer bien des problèmes. Il faudrait que je réfléchisse plus profondément à la question, mais j'entre-aperçois déjà une lumière de sagesse dans ce que tu dis.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

Discussions similaires

  1. Arguments pour et contre Access ?
    Par bottura dans le forum Sondages et Débats
    Réponses: 240
    Dernier message: 23/03/2018, 23h25
  2. Réponses: 1
    Dernier message: 16/02/2015, 16h24
  3. Instancier une classe dans son main : pour ou contre ?
    Par sphynxounet dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 17/12/2012, 16h19
  4. Réponses: 4
    Dernier message: 10/08/2012, 14h44
  5. Peut on raisonner en objets pour trouver les relations entre classes?
    Par wafiwafi dans le forum Diagrammes de Classes
    Réponses: 42
    Dernier message: 05/01/2011, 12h32

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