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 :

setter et flux


Sujet :

C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Par défaut setter et flux
    Bonjour à tous,

    Je me demandais s'il était possible d'appeler un setter à la lecture d'un flux plutôt que de passer par une variable temporaire. Ca donnerai un truc du genre:
    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
     
    class Foo
    {
    private:
      int valeur;
    public:
      void setValeur(const int newVal)
      {
        assert(newVal != 100); //par exemple ou une levée d'exception
        valeur = newVal;
      }
    };
     
    int main (void)
    {
      Foo f;
      ifstream file ("data.txt");
      file >> f.setValeur();
      file.close();
      return 0;
    }

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Non.
    Par contre, tu peux faire une fonction qui retourne une référence. Mais elle ne pourra effectuer aucun contrôle sur la valeur.
    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 Foo
    {
    private:
      int valeur;
    public:
      int & getRefValeur()
      {
          return valeur;
      }
    };
     
    int main (void)
    {
      Foo f;
      ifstream file ("data.txt");
      file >> f.getRefValeur();
      file.close();
      return 0;
    }
    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.

  3. #3
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Si on peut. En jouant avec des proxys.

    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
    struct Proxy {
        typedef int value_type; // templatisable, tout ça
        Proxy(value_type &i, value_type max ) : m_i(i), m_max(max) {}
        void set(value_type i)  { if (i<m_max) m_i=i; else throw .../return false }
    private
        value_type & m_i;
        value_type const m_max; // ou un "boost::function m_predicate;"
    };
     
    std::istream & operator>>(std::istream&is, Proxy & p) {
        Proxy::value_type i;
        if (is >> i) { p.set(i); // exception ou code de retour ?}
        return is;
    }
     
    struct A {
        Proxy setI() { return Proxy(m_i, 42); }
        Proxy setJ() { return Proxy(m_j, 100); }
    };
    A raffiner, ... tout ça.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Tu peux aussi faire une classe pour vérifier:
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    class IntSetter
    {
    public:
    	typedef bool (*check_function)(int toCheck, intptr_t userData);
     
    	explicit IntSetter(int *pInt, check_function func=0, intptr_t userData=0)
    	 : m_pInt(pInt), m_func(func), m_userData(userData)
    	{ }
     
    	bool Set(int val) const
    	{
    		bool ok = true;
    		if(m_func != 0)
    			ok = m_func(val, m_userData);
    		if(ok)
    			*m_pInt = val;
    		return ok;
    	}
     
    private:
    	int * m_pInt;
    	check_function m_func;
    	intptr_t m_userData;
    };
     
    std::istream & operator>> (std::istream & is, IntSetter const &setter)
    {
    	int val;
    	is >> val;
    	setter.Set(val);
    	return is;
    }

    Et l'utiliser ainsi:
    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
    class Foo
    {
    private:
    	int valeur;
    	static bool checkValeur(int newVal, intptr_t /*unused*/)
    	{
    		assert(newVal != 100); //par exemple ou une levée d'exception
    		if(newVal != 100)
    			return true;
    		return false;
    	}
    public:
    	IntSetter getSetValeur()
    	{
    		return IntSetter(&valeur, checkValeur);
    	}
    };
     
    int main (void)
    {
    	Foo f;
    	std::ifstream file ("data.txt");
    	file >> f.getSetValeur();
    	file.close();
    	return 0;
    }
    Edit: Mince, post croisé avant que j'aie le temps de tester mon code...
    Le code ci-dessus n'est pas testé...
    Edit2: Testé et corrigé...
    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.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Et en voici une version Template:
    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
    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    #include <iostream>
    #include <fstream>
    #include <cassert>
     
    template< class T >
    struct SetterUtil
    {
    	typedef bool (*check_function)(T toCheck);
    	typedef bool (*ref_check_function)(T const & toCheck);
    };
     
    template< class T, class Verif=typename SetterUtil<T>::ref_check_function >
    class Setter
    {
    public:
    	typedef T value_type;
    	typedef Verif check_type;
     
    	explicit Setter(value_type *pValue, check_type checker=0)
    	 : m_pValue(pValue), m_checker(checker)
    	{ }
     
    	bool Set(value_type const & val) const
    	{
    		bool ok = true;
    		if(m_checker != 0)
    			ok = m_checker(val);
    		if(ok)
    			*m_pValue = val;
    		return ok;
    	}
     
    private:
    	int * m_pValue;
    	check_type m_checker;
    };
     
    template< class T, class Verif >
    std::istream & operator>> (std::istream & is, Setter< T, Verif > const &setter)
    {
    	T val;
    	is >> val;
    	setter.Set(val);
    	return is;
    }
     
     
    class Foo
    {
    private:
    	int valeur;
    	static bool checkValeur(int newVal)
    	{
    		assert(newVal != 100); //par exemple ou une levée d'exception
    		if(newVal != 100)
    			return true;
    		return false;
    	}
    public:
    	typedef Setter<int, SetterUtil<int>::check_function> setter_type;
    	setter_type getSetValeur()
    	{
    		return setter_type(&valeur, checkValeur);
    	}
    };
     
    void TestProxy(void)
    {
    	Foo f;
    	std::ifstream file ("data.txt");
    	file >> f.getSetValeur();
    	file.close();
    }
    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.

  6. #6
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Le code ci-dessus n'est pas testé...
    T'inquiètes, le mien ne compile pas. ^^
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Par défaut
    Merci beaucoup pour vos réponses très completes. Cependant, je crois que je vais rester avec mes variables temporaires (je ne pensai pas que les solutions pouvaient être aussi "compliquées"). Encore merci à tout les deux

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Eh bien, la base est compliquée, mais la suite du code est assez réutilisable...
    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.

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

Discussions similaires

  1. Acquerir un flux audio
    Par The Cyber Lewis dans le forum DirectX
    Réponses: 1
    Dernier message: 05/04/2004, 14h13
  2. configuration getter & setter
    Par otb82 dans le forum Eclipse Java
    Réponses: 4
    Dernier message: 15/10/2003, 15h53
  3. Rediriger un flux de données sous linux
    Par Nicaisse dans le forum POSIX
    Réponses: 7
    Dernier message: 01/07/2003, 16h04
  4. Copie d'un flux dans un autre
    Par Morvan Mikael dans le forum Langage
    Réponses: 5
    Dernier message: 03/06/2003, 09h40
  5. [reseaux] redirection de flux
    Par Olive1808 dans le forum Programmation et administration système
    Réponses: 2
    Dernier message: 12/08/2002, 09h24

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