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 :

Utilité des ADT


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Mars 2005
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 28
    Par défaut Utilité des ADT
    Bonjour à tous,

    Etant passioné de developement et notemment du c++ je viens poser une question sur l'utilitée des types de données abstraites (ADT).
    Petite précision quand même je débute dans ce language que j'apprend à temps perdu. Pour en revenir à nos ADT, qui est une class contenant au moin une fonction virtuelle pure (avec obligation d'être substituée par la ou les class fille) cette derniere doit être déclarée de nouveau dans les class filles et implemantées, donc ma question pourquoi utilisée un type suplémantaire (ABSTRAIT) qui surcharge le code et qui ne fait pas gagné de temps (en therme de dévelopement)car il faut tous redefinir dans les class dérivée. Pourquoi créer une class de plus??

    Par avance merci pour vos réponses qui je l'espere seront nombreuse et precise.

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    Pour moi, un type abstrait de données n'est pas une classe contenant une fonction virtuelle pure. Un TAD (ADT je crois en anglais) est une définition d'un type indépendamment du langage. Il correspond en quelque sorte à une spécification (~ mathématique) du rôle du type, de ses états valides, des méthodes qu'il propose, en gros de son contrat. Ce type est ensuite réalisé dans un langage (par expl, le C++) par une classe abstraite, concrète ou générique ou tout autre type remplissant les spécifications du type abstrait.
    Ceci dit, l'intérêt d'avoir des classes avec des fonctions virtuelles (qui est une implémentation possible parmi d'autres d'un TAD) est un des mécanismes important de la POO puisqu'il permet à un objet client de travailler avec un autre objet fournisseur sans se soucier de comment le fournisseur est effectivement implémenté.
    Exemple, imaginons la classe suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct shape
    {
       virtual void draw() const
       {
          std::cout<<"une forme amorphe\n";
       }
       virtual ~shape(){}
    };
    Considérons la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void draw_a_shape(shape const &rs)
    { // ne connait que shape. Pas ses classes dérivées
       rs.draw();
    }
    Tu construis ton programme pour dessiner une forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main()
    {
       shape sh;
       draw_a_shape(sh);
       return 0;
    }
    Ensuite, dans ton projet, tu rajoutes une première classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct square : public shape
    {
       virtual void draw() const
       {
          std::cout<<"un carre\n";
       }
    };
    Et tu peux maintenant l'utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main()
    {
       shape sh;
       draw_a_shape(sh);
       square sq;
       draw_a_shape(sq);
       return 0;
    }
    Ton chef arrive et te demande maintenant à pouvoir dessiner des cercles. Pas de problème, grâce à l'abstraction shape, tu peux définir un nouveau type implémentant la fonction de dessin pour un cercle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct circle : public shape
    {
       virtual void draw() const
       {
          std::cout<<"un cercle\n";
       }
    };
    Et là, tu peux enrichir ton application :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main()
    {
       square sq;
       draw_a_shape(sq);
       circle c;
       draw_a_shape(c);
       return 0;
    }
    Tu vois par là que tu n'as pas besoin de modifier draw_a_shape lorsque tu veux enrichir ton application en créant de nouvelles formes. Tu dois juste créer de nouvelles classes héritant de shape et spécialisant la fonction virtuelle. Des objets de cette nouvelle classe sont utilisables partout où tu as utilisé l'abstraction shape sans avoir à modifier ce code. Tu as ainsi gagné sur au moins deux tableaux :
    -> tes nouvelles classes peuvent instantanément bénéficier du code existant. En effet, partout où tu utilises la classe de base, tu peux utiliser un objet de la classe dérivée ;
    -> tu as découpler tes classes/fonctions du type réellement utilisé. Lorsque tu rajoutes une nouvelle classe dérivée, tu n'as pas besoin de venir modifier les classes ou les fonctions existantes qui utilises la classe de base.
    Ceci devrait te faire sentir toute l'utilité de classe contentant des fonctions virtuelles et servant de base à un héritage publique.

    Ensuite, pourquoi des fonctions virtuelles pures dans certaines classes ? Tout simplement parce que l'abstraction de ta classe de base peut ne pas avoir d'implémentation associée. La classe de base propose une abstraction qui devra forcément être réalisée par une classe concrète. Elle ne propose pas de comportement par défaut car ça n'aurait pas de sens à ce niveau d'abstraction.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct i_generic_shape
    {
       virtual void draw() const = 0;
       virtual ~i_generic_shape(){}
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void draw_a_shape(i_generic_shape const &rs)
    {
       rs.draw();
    }
    Puis ensuite tes classes concrètes :
    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
    struct blob_shape : public i_generic_shape
    {
       virtual void draw() const
       {
          std::cout<<"une forme amorphe\n";
       }
    };
     
    struct square : public i_generic_shape
    {
       virtual void draw() const
       {
          std::cout<<"un carre\n";
       }
    };
     
    struct circle : public i_generic_shape
    {
       virtual void draw() const
       {
          std::cout<<"un cercle\n";
       }
    };
    Ici i_generic_shape ne propose pas de réalisation concrète de la fonction draw. Toutes les fonctions peuvent encore utiliser i_generic_shape pour demander à les dessiner sans avoir à connaître les classes concrètes dérivant de i_generic_shape. i_generic_shape ne peut être instanciée. Nous devons définir des classes concrètes qui elles seront réellement instanciées.

  3. #3
    Membre averti
    Inscrit en
    Mars 2005
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 28
    Par défaut
    Il me semble avoir un peu mieux compris dans la fonction globale( enfin je pense)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    draw_a_shape(shape const &rs);
    si on passe un objet dérivé de schape à la fonction ci dessus le principale interêt des fonctions virtuelles est de créer dynamiquement le lien avec la bonne fonction ou je me trompe.

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par lolotte Voir le message
    si on passe un objet dérivé de schape à la fonction ci dessus le principale interêt des fonctions virtuelles est de créer dynamiquement le lien avec la bonne fonction ou je me trompe.

    C'est exactement ça. La résolution de l'appel est faite à l'exécution selon le type dynamique de l'objet (le type effectif).

  5. #5
    Membre averti
    Inscrit en
    Mars 2005
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 28
    Par défaut
    Merci pour t'es explications qui mon aidé à mieux comprendre le role des ADT et des fonctions virtuelles.

    Merci encore.

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    En revanche, j'espère que tu as compris que ADT est différent de fonction virtuelle pure & classe abstraite .
    ADT = définition 'mathématique d'un type'.
    Classe abstraite = classe avec une 1 fn virtuelle pure = implémentation d'un ADT.
    classe concrète = implémentation d'un ADT.

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

Discussions similaires

  1. Utilité des types OpenGL GLint, GLfloat, GLvoid, etc.
    Par Djakisback dans le forum OpenGL
    Réponses: 17
    Dernier message: 14/12/2005, 12h35
  2. utilité des tables ??
    Par shadowmoon dans le forum Langage SQL
    Réponses: 6
    Dernier message: 02/06/2005, 09h43
  3. Utilité des schemas sous Postgresql?
    Par sessime dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 18/03/2005, 15h45
  4. Utilité des logos Xiti ?
    Par KibitO dans le forum Evolutions du club
    Réponses: 5
    Dernier message: 20/02/2005, 17h42
  5. utilité des DbControl
    Par portu dans le forum Bases de données
    Réponses: 6
    Dernier message: 02/07/2004, 05h41

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