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 :

question a propos d'héritage


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 6
    Par défaut question a propos d'héritage
    je dispose d'une classe message
    dont héritent les classes messages1, message2, message3

    j'ai un objet message * m

    que j'instancie suivant la valeur d'un entier
    si i = 1 : m = new Message1
    si i = 2 : m = new Message2
    ...

    Je cherche un moyen d'automatiser cette instanciation.

    par exemple en déclarant les différentes classes message1 message2 dans un tableau
    et que mon programme crée un objet message1 quand i = 1 sans que cela soit explicitement ecrit dans le code.
    Le but étant lors de l'ajout d'un message_i de n'avoir qu'a compléter ce tableau et
    pas avoir a rajouter tous les endroits ou l'objet peut etre instancié dans le code.

    est ce faisable ? si oui, comment ?
    merci pour vos pistes.

  2. #2
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Si i est connu seulement à l'execution, il va faloir forcément passer par un truc un peu sale comme tu as.

    Si il est connu a la compilation, tu peux passer par un template : Message<i>

  3. #3
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 293
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    je ne connais pas la raison pour laquelle tu as cet héritage, je ne peux donc pas être trés précis dans ma réponse. Mais une solution est possible, c'est, comme le propose NiarmorH, de transformer ta classe message en classe template.

    Si cette solution n'est pas possible, il y d'autres solutions qui consistent à utilisent l'héritage autrement. Je pense notamment au DP template method.

    A voir selon ce que tu souhaites faire exactement avec cette classe message.

  4. #4
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Je doute très très fort que le template soit la solution à retenir ici.

    Je pense que ce dont tu as besoin est une fabrique ou un monteur.

  5. #5
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 293
    Billets dans le blog
    2
    Par défaut
    Bah, si toutes les classes filles ont la même interface (j'entend par là l'ensemble des méthodes publiques), pourquoi pas?

  6. #6
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Citation Envoyé par r0d Voir le message
    Bah, si toutes les classes filles ont la même interface (j'entend par là l'ensemble des méthodes publiques), pourquoi pas?
    Ca n'apportera rien si i n'est connu qu'à l'éxécution.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    IMessage *
    GetMessage( int i )
    {
      return new Message<i>();
    };
    Ne compilera pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <int i>
    Message<i>
    GetMessage<i>()
    {
      return Message<i>();
    };
    Celui-ci marcherait.

    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
    enum MessageList
    {
      ALERT = 0,
      ERROR = 1,
      INFO   = 3
    };
     
    int main()
    {
      MessageVector vec;
      vec.push_back( new Message<MessageList::ALERT>() );
      vec.push_back( new Message<MessageList::ERROR>() );
      vec.push_back( new Message<MessageList::INFO>() );
      for_each( vec.begin(), vec.end(), display() );
    }
    Marcherait aussi, mais ce qu'il cherche à faire est factoriser la création avec un i à l'éxécution et ça c'est pas faisable.

  7. #7
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    La fabrique est ici toutes bien venu.
    En effet, elle permet de crée des d'objets dérivant d'une même classe de facon transparent en se basant sur des clé de nimporte quel type pour instancier tes objets.
    Voici un exemple de fabrique basé sur les templates et une création d'objet via prototypage:
    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    #include <iostream>
    #include <map>
    #include <iterator>
    #include <string>
     
    using namespace std;
     
    //la classe prototype
    template <class T> class Prototype
    {
    	public:
    	virtual ~Prototype(){}	
    	virtual T* Clone() const =0 ;
    };
     
    //l'interface "Figure" 
    class Figure : public  Prototype<Figure>
    {
    	public: 
    	virtual void SeDessiner()=0;
    };
     
    class Carre : public Figure 
    {
    public:
    	Figure* Clone() const ;
    	void SeDessiner();
    };
     
    class Cercle : public Figure 
    {
    public:
    	Figure* Clone() const ;
    	void SeDessiner();
    };
     
    //La fabrique a proprement parler
    template <class Object,class Key=string> class Factory
    {
    std::map<Key,Object*> m_map;
    public:
     
    	//La fonction qui va créer les objets
    	Object* Create(const Key& key) const ;
     
    	//Celle qui associe clé <=> prototype
    	void Register(Key key,Object* obj);
    };
     
     
     
    Figure* Carre::Clone() const 
    {
     return new Carre(*this);
    }
     
    void Carre::SeDessiner()
    {
    cout<<"Je suis un Carre"<<endl;
    }
     
     
    Figure* Cercle::Clone() const 
    { 
    	return new Cercle(*this);
    }
     
    void Cercle::SeDessiner()
    {
    	cout<<"Je suis un Cercle"<<endl;
    }
     
     
     
    template <class Object,class Key> void Factory<Object,Key>::Register(Key key,Object* obj)
    {
    //si la clé n'est pas déja présente
    		if(m_map.find(key)==m_map.end())
          	{
    			//on ajoute l'objet dans la map
    			m_map[key]=obj;
    		}
    //on pourrai détruire obj mais cette tache ne revient pas à la Register
    }
     
    template <class Object,class Key> Object* Factory<Object,Key>::Create (const Key& key) const 
    {
    		Object* tmp=0;
     
    		typename std::map<Key, Object*>::const_iterator it=m_map.find(key);
     
    		//si l'itérateur ne vaut pas map.end(),cela signifique que la clé à été trouvé     
    		if(it!=m_map.end())
    		{
    			//donc on clone l'objet
    	      	tmp=((*it).second)->Clone();
          	}
    //on pourrai lancer une exeption au besoin
    		return tmp;
    }
     
     
     
    int main(void)
    {
     Factory<Figure> fac;
     
     fac.Register("Carre",new Carre);
     fac.Register("Cercle",new Cercle);
     
      Figure *c=fac.Create("Cercle");
      Figure *ca=fac.Create("Carre");
     
      c->SeDessiner();
      ca->SeDessiner();
     
      delete c;
      delete ca;
     
      return 0;
    }
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  8. #8
    Alp
    Alp est déconnecté
    Expert confirmé

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    En effet, le Design Pattern Factory est ici ce qu'il faut.
    J'allais le suggérer avant de lire ton message David

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

Discussions similaires

  1. Question a propos de LWP::Parallel::UserAgent
    Par shinux2004 dans le forum Modules
    Réponses: 2
    Dernier message: 03/09/2005, 02h01
  2. Question a propos de threads
    Par cryptorchild dans le forum Langage
    Réponses: 1
    Dernier message: 12/07/2005, 10h03
  3. [VBA-E] Question à propos des checkbox
    Par Timfg dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 26/04/2005, 15h09
  4. Question a propos des modulos
    Par barthelv dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 24/03/2005, 15h56
  5. [debutant] Questions a propos du XML
    Par brune dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 04/06/2004, 09h39

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