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 :

Héritage et simplification d'écriture


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 54
    Points : 20
    Points
    20
    Par défaut Héritage et simplification d'écriture
    Salut tout le monde

    Je vous explique mon problème :
    J'ai une classe de base B
    puis je dérive trois classe de B -> D1, D2, et D3 (en héritage public)

    Ensuite c'est la que pose le problème puisque je me retrouve avec plusieurs instaciations de chaque classe D1, D2, et D3.
    Ainsi dans une autre classe Manager j'écris :
    D1 * d1[10];
    D2 * d2[10];
    D3 * d3[10];

    Donc D1 D2 et D3 sont dérivées de la classe de base B, mais mon souci c'est que j'ai plein de sous classe derivée de B (pas que comme dans cet exemple)

    Ainsi pour pouvoir utiliser la fonction calculer() qui se trouve dans chaque D1 , D2 et D3, je dois écrire :

    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
     
    int i, j;
    for (i=1; i<=3; i++)  // on parcourt les d1, d2 et d3
    {
    for (j=0; j<10; j++) // on parcourt les 10 instanciations de chaque dx
    {
    switch (i)
    {
    case 1 : d1[j]->calculer(); break;
    case 2 : d2[j]->calculer(); break;
    case 3 : d3[j]->calculer(); break;
    }
    d1[i]
    }
    }
    Donc voila si je veux rajouter encore 10 derivées de la classe B (de D1 à D30) il faut que je m'amuse a ecrire autant de fois ces lignes, ce qui est long est rend le code difficile a mettre a jour

    Connaissez-vous une méthode pour utiliser eventuellement la classe de base B pour écrire une seule fois la ligne mais utiliser la bonne fonction dans D

    J'espere que vous m'ayez compris car c'est un peu dur a expliquer

  2. #2
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Points : 325
    Points
    325
    Par défaut
    Tu as commencé à utiliser l'héritage, et tu t'es arreté avant d'utiliser le polymorphisme...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    B * d[30];
     
    d[0] = new D1;
    d[1] = ...
    ...
    d[9] = new D1;
    d[10] = new D2;
    ...
     
     
    for (j=0; j<30; ++j)
       d[j]->calculer();
    voila une méthode...

    L'instanciation reste laborieuse a moins d'utiliser une fonction "Factory" par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    B* Create(int i)
    {
       B* result = NULL;
       if (i<10)
          result = new D1;
       else if (i<20)
          result = new D2;
    ...
       return result;
    }
     
     
    }

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 54
    Points : 20
    Points
    20
    Par défaut
    C'est pas exactement ce que je voulais faire Gandalf.

    Je prend un autre exemple.
    J'ai la classe de base CVoiture et deux classes dérivées de CVoiture comme CFerrari et CSeat

    J'ai mes tableaux pour mes différentes ferrari et seat (10 pour l'instant)

    CFerrari * ferrari[10];
    CSeat * seat[10];

    donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    int i, j;
     
    for (i=0; i<2; i++)
    {
       for (j=0; j<10; j++)
       {
           switch(i)
           {
             case 0 : ferrari[j] = new CFerrari(); break;
             case 1 : seat[j] = new CSeat(); break;
           }
       }
    }
    Et donc si je rajoute mercedes il faut aussi que je rajoute un autre case etc.. et ce pour toutes les fonctions. Car une voiture ensuite il faut demarer(), puis rouler() et ensuite arreter(). Ca veut dire qu 'il faut rajouter je ne sais combien d'instanciation dans chacune de ces fonctions alors que le coportement est exactement le même que les autre voitures sauf que c'est le nom qui change

    Vous voyez un peu mieux d'où vient mon problème

  4. #4
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    le comportement est exactement le même que les autre voitures sauf que c'est le nom qui change
    Est-ce que l'héritage était vraiment justifié alors ? Pourquoi pas simplement des instances de CVoiture, avec un attribut nom qui diffère ?
    And still we will be here, standing like statues ...

  5. #5
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    La solution de Gandalf semble pourtant correcte. Ton problème vient de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CFerrari * ferrari[10]; 
    CSeat * seat[10];
    qui devrait être
    La création demande ce switch mais sous la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      switch(i) 
       { 
          case 0 : voiture[j] = new CFerrari(); break; 
          case 1 : voiture[j] = new CSeat(); break; 
       }
    mais ensuite tu peux utiliser
    sans switch
    Si tu rajoutes CMercedes, il faut ajouter un case dans la fonction de création et (éventuellement) personnaliser la fonction demarrer() de la classe CMercedes
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 54
    Points : 20
    Points
    20
    Par défaut
    A bigquick, non au fait le comportement est différent entre chaque voiture mais les noms de fonctions restent quasiment identiques entre chaque dérivée de voiture.

    A diogene :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      switch(i)
       {
          case 0 : voiture[j] = new CFerrari(); break;
          case 1 : voiture[j] = new CSeat(); break;
       }
    Ha en effet c'est interessant, mais je savais pas que c'était possible en C++.

    Rectification : J'ai eu un autre soucis en essayant cela.

    J'ai utilisé la méthode ci dessus en ne déclarant qu'un tableau de voiture[] et pour les construire j'utilisais la classe derivée adéquate (c'est ok ca marche). Mais maintenant lorsque j'appel la fonction voiture[j]->demarrer(); le programme se dirige dans la fonction demarrer dans la classe de base CVoiture alors qu'il faudrait qu'il aille directement dans la fonction demarrer() de la classe CFerrari ou CSeat (correspondante au constructeur) , je ne sais pas s'il faut utilisé des virtual ou pas? mais je suis un peu coincé la!!

    Pourtant j'ai bien utilisé le même prototypage dans la classe de base et la dérivée ???

    Que faire?

  7. #7
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Points : 325
    Points
    325
    Par défaut
    Je ne sais quoir repondre...

    Ton second exemple n'apporte rien, il est un transposition du premier...

    Si tu veux dire que tu souhaite garder tes tableaux distintcs, tu peux construire un tableau unions des différents tableaux.

    Si l'héritage ne se justifie pas, n'en fait pas ! Passe en en template ce qui te permettra de jouer sur le fait que les fonctions aient le même nom...

    Bien entendu pour ce que j'aoi proposé marche il faire l'héritage correctement, c'est-à-dire que les fonction redéfinies soient "virtual" dans la classe mère. Peux être que la declaration de la classe mère n'aurrait pas été inutile... ...bien entendu on en peut commenter que ce que l'on voit.

  8. #8
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    je ne sais pas s'il faut utilisé des virtual ou pas?
    Oui en effet pour que le polymorphisme puisse fonctionner completement, il faut ajouter le mot-clé virtual, qui va "demander" une liaison dynamique. Ainsi, au moment d'appeler demarrer(), il appellera la méthode qui correspond au type réel de l'instance (par exemple CSeat) et non pas à son type apparent (CVoiture, puisque c'est un tableau de CVoiture*).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class CVoiture
    {
           virtual void demarrer() = 0;    // le =0 oblige les classes filles à redéfinir cette méthode
    };
     
    class CSeat : public CVoiture
    {
           void demarrer();
    };
    And still we will be here, standing like statues ...

Discussions similaires

  1. [PDO] bindParam simplification d'écriture ?
    Par Pandora dans le forum PHP & Base de données
    Réponses: 14
    Dernier message: 02/07/2013, 08h11
  2. [XL-2010] Simplification d'écriture du code
    Par canary dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 02/01/2013, 15h56
  3. [Postgres] Héritage + Clés
    Par k-reen dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 21/05/2003, 16h37
  4. [Kylix] Simplifications de l'écriture Kylix/Pascal"
    Par Mr Vincent KLEIN dans le forum EDI
    Réponses: 1
    Dernier message: 11/03/2003, 11h07
  5. Héritage entre Forms
    Par BarBal dans le forum Composants VCL
    Réponses: 7
    Dernier message: 29/08/2002, 17h44

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