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 :

Interdire à une classe d'appeler une méthode et le permettre à une autre


Sujet :

C++

  1. #1
    Membre averti Avatar de AL1986
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    434
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 434
    Points : 441
    Points
    441
    Par défaut Interdire à une classe d'appeler une méthode et le permettre à une autre
    Salut,

    Je dispose d'une classe Classe dont le code ressemble à ça
    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
    class Classe {
     
    public:
    	Classe(){};
    	virtual ~Classe(){};
     
    //quelques attributs private et des setters et getters public
     
    private:
    	bool _attribut;
    public:
    	const bool& getAttribut() {
    		return _attribut;
    	};
    	void setAttribut(bool iAttribut) {
    		_attribut = iAttribut;
    	};	
    };
    J'aimerai permettre à une autre classe C1 d'appeler le getter mais pas le setter. Pour le getter, il n y a pas de problème, par contre le setter est appelé par une autre classe C2, c'est pour cela que je l'ai mis public. Par conséquent, je ne peux empêcher C1 de faire appel à ce setter. Comment devrai-je faire afin d'y lui interdire l'accès sachant que je n'ai aucun contrôle sur C1 ?
    Merci pour votre aide.
    Etre ou ne pas être, telle est la question sinusoïdale de l'anachorète hypocondriaque et vice et versa .
    Bonsai monsieur, bonsai madame, vous avez gagnez un milliard de degrés au soleil .
    There is no cure for stupidity (ou pas ).

  2. #2
    Membre confirmé
    Avatar de NewbiZ
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2002
    Messages
    184
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2002
    Messages : 184
    Points : 563
    Points
    563
    Par défaut
    C'est un peu étrange comme conception...
    Typiquement, tu ne peux pas connaitre l'appelant d'une méthode (dommage), il te reste donc à mon sens 2 possibilités :

    1) Passer le setter en privé, et spécifier une amitié pour les classes pouvant appeler le setter. Problème: elles auront aussi accès aux autres fonctions privées.

    2) Demander explicitement à l'appelant de s'identifier (enum ou pointeur sur son instance ou template), et surcharger le setter en conséquence. Problème: rien n'empeche que l'appelant tricher, et ca salit considérablement les appels.

    3) Essayer de rendre la chose cachée, et utiliser l'héritage, encore une fois, c'est pas vraiment parfait, ca repose sur un topcast.
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    #include <iostream>
    #include <cstdlib>
     
    class Foo
    {
    public:
      Foo() : m_bar(0) {}
      virtual ~Foo()   {}
     
      const int& getBar() const    { return m_bar; }
     
    protected:
      virtual void setBar( int bar ) { m_bar = bar;  }
     
    private:
      int m_bar;
    };
     
    class FooUnsecured : public Foo
    {
    public:
      virtual void setBar( int bar ) { Foo::setBar(bar); }
    };
     
    class Trusted
    {
    public:
      void giveMeFoo( FooUnsecured* foo )
      {
        std::cout << "Trusted::giveMeFoo()" << std::endl;
        std::cout << "foo->getBar() = " << foo->getBar() << std::endl;
        foo->setBar( 10 );
        std::cout << "foo->getBar() = " << foo->getBar() << std::endl;
      }
    };
     
    class Untrusted
    {
    public:
      void giveMeFoo( Foo* foo )
      {
        std::cout << "Trusted::giveMeFoo()" << std::endl;
        std::cout << "foo->getBar() = " << foo->getBar() << std::endl;
        foo->setBar( 10 ); // Erreur
        std::cout << "foo->getBar() = " << foo->getBar() << std::endl;
      }
    };
     
    int main( int, char** )
    {
      FooUnsecured* foo = new FooUnsecured();
      Untrusted untrusted;
      Trusted   trusted;
     
      untrusted.giveMeFoo( foo );
      trusted.giveMeFoo  ( foo );
     
      return EXIT_SUCCESS;
    }

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ou bien, tout simplement rendre ta classe const-correcte :
    Code C++ : 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
    class Classe {
     
    public:
    	Classe(){};
    	virtual ~Classe(){};
    	
    //quelques attributs private et des setters et getters public
     
    private:
    	bool _attribut;
    public:
    	const bool& getAttribut() const {
    		return _attribut;
    	};
    	void setAttribut(bool iAttribut) {
    		_attribut = iAttribut;
    	};	
    };
    Ainsi, il te suffit de passer un pointeur const Classe * à la classe dont tu ne veux pas qu'elle puisse appeller le setter...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    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
    Autre solution: ne pas se prendre la tête avec ce genre de détails

    Qui écrit C1 et C2 ? Si c'est toi, alors à priori il n'y a pas de problème. Si ce n'est pas toi, alors pourquoi interdire l'appel ?
    [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.

  5. #5
    Membre averti Avatar de AL1986
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    434
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 434
    Points : 441
    Points
    441
    Par défaut
    Merci pour vos réponses.

    Citation Envoyé par Emmanuel Deloget Voir le message
    Autre solution: ne pas se prendre la tête avec ce genre de détails

    Qui écrit C1 et C2 ? Si c'est toi, alors à priori il n'y a pas de problème. Si ce n'est pas toi, alors pourquoi interdire l'appel ?
    C'est moi qui écrit C2. Par contre, C1 sera écrite par quelqu'un d'autre qu'on appelera client. J'aimerai permettre au client de ne "voir" que les données dont il a besoin. Il se trouve qu'il a besoin d'avoir accès à tous les éléments de Classe sauf le setter de _attribut.
    Etre ou ne pas être, telle est la question sinusoïdale de l'anachorète hypocondriaque et vice et versa .
    Bonsai monsieur, bonsai madame, vous avez gagnez un milliard de degrés au soleil .
    There is no cure for stupidity (ou pas ).

  6. #6
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Salut,

    Citation Envoyé par AL1986 Voir le message
    J'aimerai permettre au client de ne "voir" que les données dont il a besoin. Il se trouve qu'il a besoin d'avoir accès à tous les éléments de Classe sauf le setter de _attribut.
    Tu définis une interface (une classe avec que des méthodes virtuelles pures) C implémentée par C2 et tu passes C à C1 au lieu de C2.
    Ça permet de contrôler précisément ce que C1 manipule tout en masquant complètement l'implémentation.

    MAT.

  7. #7
    Membre à l'essai
    Inscrit en
    Janvier 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 13
    Points : 15
    Points
    15
    Par défaut
    salut

    bon je sais pas si ca t'interesse mais jette un coup d'oeuil sur les fonction amis.

    freind permet l'acces des fonctions aux attribus meme s'elles sont pas membres de la classe d ces attribus !



    j'espere que j'ajoute qlqchose !

    bone chance

  8. #8
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Soit de la généricité (template) soit de l'héritage permettent de résoudre ton problème. Je préfère la méthode avec les templates.

  9. #9
    Membre averti Avatar de AL1986
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    434
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 434
    Points : 441
    Points
    441
    Par défaut
    Merci pour vos réponses.
    Citation Envoyé par wakaa3lik Voir le message
    salut

    bon je sais pas si ca t'interesse mais jette un coup d'oeuil sur les fonction amis.

    freind permet l'acces des fonctions aux attribus meme s'elles sont pas membres de la classe d ces attribus !



    j'espere que j'ajoute qlqchose !

    bone chance
    NewBiz m'a déjà proposé d'utiliser l'amitié mais cela donne aussi accès aux autres attributs privés.
    Citation Envoyé par NewbiZ Voir le message
    1) Passer le setter en privé, et spécifier une amitié pour les classes pouvant appeler le setter. Problème: elles auront aussi accès aux autres fonctions privées.
    Je pense que je vais opter pour l'une de ces deux solutions :
    Citation Envoyé par NewbiZ Voir le message
    3) Essayer de rendre la chose cachée, et utiliser l'héritage, encore une fois, c'est pas vraiment parfait, ca repose sur un topcast.
    Citation Envoyé par Alp Voir le message
    Soit de la généricité (template) soit de l'héritage permettent de résoudre ton problème. Je préfère la méthode avec les templates.
    Merci à tous.
    Etre ou ne pas être, telle est la question sinusoïdale de l'anachorète hypocondriaque et vice et versa .
    Bonsai monsieur, bonsai madame, vous avez gagnez un milliard de degrés au soleil .
    There is no cure for stupidity (ou pas ).

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 22/07/2014, 22h40
  2. Réponses: 13
    Dernier message: 23/05/2013, 20h38
  3. Choix d'une classe pour appel de méthodes statiques
    Par Antwan76ers dans le forum Débuter avec Java
    Réponses: 11
    Dernier message: 05/07/2012, 10h55
  4. Demander à une classe l'appel à une méthode
    Par sliderman dans le forum Langage
    Réponses: 3
    Dernier message: 22/01/2008, 14h45
  5. Réponses: 3
    Dernier message: 16/04/2004, 16h51

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