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 :

Mauvaise modelisation ?


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 59
    Par défaut Mauvaise modelisation ?
    Bonjour a tous, je débute en c++ et je tente de résoudre le problème suivant :

    J'ai une classe de base qui contient toutes les variables et méthodes communes pour les classes dérivées.

    Je dois ensuite créer les classes dérivées qui contiendront des spécifications mais le problème c'est que ces spécifications ne seront connues qu'a l'exécution du programme (les spécifications sont dans un fichier) et non a la compilation.

    Exemple :

    - J'ai une classe Vehicule qui est la classe de base
    - Je veux créer des classes dérivées Voiture, Moto, ... mais pour cela j'ai besoin d'informations dans un fichier donc je doit créer ces classes a l'exécution du code (par exemple une voiture a 4 roues, une moto 2, un bateau a une hélice, ...).
    - J'ai besoin de ce fichier car les utilisateurs pourront charger d'autres fichiers pour modifier les spécifications des véhicules.
    - Ces classes dérivées me permettront de créer des objets Ferrari, Honda, ... par exemple

    Avec cet exemple ce n'est pas très explicite, je pourrai le faire autrement mais dans mon cas, il est nécessaire que je charge des informations d'un fichier pour créer ces classes dérivées.

    Donc ma question est :

    Est il possible de créer des classes dynamiquement ? (a l'exécution du code)
    Si oui, est ce une bonne méthode ?
    Si non, est ce la modélisation du problème qui est mauvaise et y a t'il moyen de faire autrement ?

    Merci

  2. #2
    Membre éprouvé
    Inscrit en
    Avril 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 155
    Par défaut
    C'est peut être la fin de journée mais je vois pas trop le problème
    ==> créer des classe dynamiquement...heu, tu veux dire plutôt créer des objets dynamiquement?parce que je vois pas trop comment en lisant un fichier à l'exécution tu générerais un code de classe...

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    On ne peut pas créer une classe dynamiquement.
    Mais on peut créer des objets dynamiquement, et on peut toujours créer des structures de données dynamiquement si on a fait le code pour les gérer...
    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
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 14
    Par défaut
    Le C++ est un langage à typage statique, ce qui veut dire que les types (y compris les classes) doivent être connus à la compilation. Ainsi en cas de problèmes, il y aura une erreur à la compilation et non à l'exécution.

    Même en admettant que ça soit possible, ça ne serait pas une bonne solution, ce n'est pas la philosophie du langage.

    Pour résoudre ton problème, tu peux faire des classes dérivés "VehiculeARoues", "VehiculeAHelice", "VehiculeAReacteur", etc... et à l'éxecution, l'utilisateur choisit quelle classe il faut utiliser, mais l'utilisateur ne devrait jamais créer des classes (il peut juste en instancier...)

  5. #5
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 59
    Par défaut
    Citation Envoyé par loicounet Voir le message
    C'est peut être la fin de journée mais je vois pas trop le problème
    ==> créer des classe dynamiquement...heu, tu veux dire plutôt créer des objets dynamiquement?parce que je vois pas trop comment en lisant un fichier à l'exécution tu générerais un code de classe...
    Non pas d'objets, je ne parle pas d'allocation, je parle de classes :

    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
     
    class vehicule
    {
     public :
      vehicule() { nbrwheel = 0; };
     
    protected :
      void setWheelNumber (int n) {nbrwheel = n; };
     
     private :
      int nbrwheel;
    };
     
    class voiture : public vehicule
    {
     public :
      voiture() { setWheelNumber(4); };
    };
     
    ...
    Ensuite je peux créer des voitures Suzuki, Opel, ...

    Sauf que le "4" (roues), je ne le connais pas mais je dois le charger dans un fichier.

    J'imagine qu'on ne sait pas créer de classes 'dynamiquement' puisqu'a la compilation les liens de méthodes, classes, ... sont résolus (en C++, peut etre qu'il est possible de le faire en objective C) mais alors est ce une mauvaise conception, y a t'il moyen de le faire autrement ?

    Merci

  6. #6
    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
    Dans ce genre de chose, il faut différencier ce qui est constant de ce qui ne l'est pas. Toutes les voitures on un paramètre qui spécifie le nombre de places ou la puissance du moteur. Il en va de même pour les autres types de véhicules. Des lors, ces différentes caractéristiques
    doivent être héritées d'une même classe mère.

    Ce qui change, c'est la valeur des ces caractéristique pour chaque objet. En effet, un Ferrari n'a pas la même puissance qu'une Honda. Mais toute les 2 ont un attribut puissance. Des lors, pour créer des différents véhicules à partir de spécification fourni chargées, pour moi le mieux est de créer une classe qui va avoir pour rôle de gérer la création de véhicules à partir d'un fichier donné en argument (c'est un design pattern : la fabrique).

    Ce qui donne quelque chose 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    class Vehicule
    {
     public :
      Vehicule(int nbplace,int puissance):m_nbplace(nbplace),m_puissance(puissance) {};
     
    protected :
      int m_nbplace,m_puissance;
    };
     
    class Voiture : public Vehicule
    {
    //des choses spécifique à Voiture
     public :
      voiture(int nbplace,int puissance):Vehicule(nbplace,puissance) {};
    };
     
     
    class FabriqueVehicule
    {
    public:
    Voiture* CreateVoiture(const std::string& path)
            {
     
            std::istream fichier(path);        
     
            int puissance=0; int nbplace=0;
            fichier>>nbplace>>puissance;
     
            return new Voiture(nbplace,puissance);
            }
    };
    avec une utilisation du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    FabriqueVehicule fab.
    Voiture* ferrai = fab.CreateVoiture("ferrai.def");
    PS: il me semble que tu confond objet et classe.
    Une classe est un moule à partir du quel on créer des objets.
    "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)

  7. #7
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 59
    Par défaut
    Citation Envoyé par mazipha Voir le message
    Le C++ est un langage à typage statique, ce qui veut dire que les types (y compris les classes) doivent être connus à la compilation. Ainsi en cas de problèmes, il y aura une erreur à la compilation et non à l'exécution.

    Même en admettant que ça soit possible, ça ne serait pas une bonne solution, ce n'est pas la philosophie du langage.

    Pour résoudre ton problème, tu peux faire des classes dérivés "VehiculeARoues", "VehiculeAHelice", "VehiculeAReacteur", etc... et à l'éxecution, l'utilisateur choisit quelle classe il faut utiliser, mais l'utilisateur ne devrait jamais créer des classes (il peut juste en instancier...)
    C'est bien ce que je pensait, mais le probleme est que ces spécifications sont dans un fichier et si je dois créer toutes les classes a l'avance et qu'en fonction du fichier j'instancie telle ou telle classe, le jour ou le fichier contiendra un nouveau type de vehicule dont je n'ai pas la classe, ca ne fonctionnera plus.

    Je pense que je vais devoir créer juste une classe de base qui aura une methode statique qui chargera le fichier et qui changera les parametres des objets instanciés.

    Un genre 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
    19
    20
    21
    22
    23
    24
    25
     
     
    class vehicule
    {
     public :
      vehicule(char *name);
      static int loadFile (char *filename);
    ...
     
     private :
      char name[64];
    ...
    };
     
    // Charger le fichier de spécifications
    vehicule::loadfile("fichier");
     
    // Créer un nouvel objet voiture
    vehicule voiture("voiture");
     
    // Créer un nouvel objet voiture
    vehicule voiture2("voiture");
     
    // Créer un nouvel objet moto
    vehicule moto("moto");
    avec le constructeur qui en fonction du nom recu, va initialiser les parametres en fonction du fichier chargé auparavant.

    A moins qu'il n'y ait une meilleure solution ?

    Merci

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 14
    Par défaut
    Je ne suis pas sur d'avoir bien compris ce que tu veux faire, mais voici peut être une piste: Le fameux "4", je le remplacerais par un paramètre du constructeur.
    Ensuite en admettant que tu ais codé une fonction "lireNbredeRouesDansFichier" qui va lire les valeurs dans ton fichiers. Je crée trois instances de voiture (Honda, Suzuki, Opel) de cette façon:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class voiture : public vehicule
    {
     public :
      voiture(int nbrwheel) { setWheelNumber(nbrwheel); };
    };
     
    int main()
    {
       voiture Honda(lireNbredeRouesDansFichier("Honda"));
       voiture Suzuki(lireNbredeRouesDansFichier("Suzuki"));
       voiture Opel(lireNbredeRouesDansFichier("Opel"));
    }

  9. #9
    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
    A chaque classe un seul et unique rôle.
    Une voiture c'est un nombre de roues, un puissance, elle n'a pas à lire les les spécifications qui la définissent.c'est au créateur de la voiture de lire ces spécifications pour ensuite les fournir au constructeur de voiture.
    "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)

  10. #10
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 59
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Dans ce genre de chose, il faut différencier ce qui est constant de ce qui ne l'est pas. Toutes les voitures on un paramètre qui spécifie le nombre de places ou la puissance du moteur. Il en va de même pour les autres types de véhicules. Des lors, ces différentes caractéristiques doivent être héritées d'une même classe mère.

    Ce qui change, c'est la valeur des ces caractéristique pour chaque objet. En effet, un Ferrari n'a pas la même puissance qu'une Honda. Des lors, pour créer des différents véhicules à partir de spécification fourni chargées, pour moi le mieux est de créer une classe qui va avoir pour rôle de gérer la création de véhicules à partir d'un fichier donné en argument.

    Ce qui donne quelque chose 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    class Vehicule
    {
     public :
      Vehicule(int nbplace,int puissance):m_nbplace(nbplace),m_puissance(puissance) {};
     
    protected :
      int m_nbplace,m_puissance;
    };
     
    class Voiture : public Vehicule
    {
     public :
      voiture(int nbplace,int puissance):Vehicule(nbplace,puissance) {};
    };
     
     
    class FabriqueVehicule
    {
    public:
    Voiture* CreateVoiture(const std::string& path)
            {
     
            std::istream fichier(path);        
     
            int puissance=0; int nbplace=0;
            fichier>>nbplace>>puissance;
     
            return new Voiture(nbplace,puissance);
            }
    };
    avec une utilisation du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    FabriqueVehicule fab.
    Voiture* ferrai = fab.CreateVoiture("ferrai.def");
    PS: il me semble que tu confond objet et classe.
    Une classe est un moule à partir du quel on créer des objets.
    Merci, oui je pense que c'est la meilleure solution.
    Je ne confond pas objet et classe , je sais que la classe c'est le type et que l'objet c'est la 'variable' un peu comme int x; avec int la classe et x l'objet.

    Mais c'est parce que mon projet est plus complexe que l'exemple des voitures et je pensait qu'on pouvait mieux utiliser les avantages du c++ dans ce probleme (car la technique de FabriqueVehicule me fait plus penser a de la programmation fonctionnelle).

    Merci a tous

Discussions similaires

  1. Les Meilleurs Outils de Modélisation UML ?
    Par Matthieu Brucher dans le forum Outils
    Réponses: 76
    Dernier message: 06/11/2015, 12h48
  2. Recherche d'outil de modelisation
    Par Matthieu Brucher dans le forum Outils
    Réponses: 33
    Dernier message: 14/11/2014, 11h37
  3. Modelisation OLAP
    Par Guizz dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 17/06/2003, 10h11
  4. Réponses: 3
    Dernier message: 04/09/2002, 09h42

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