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ériter de list ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 33
    Par défaut Hériter de list ?
    Bonjour et bonne année à tous

    Je débute en C++ (mais j'ai de bonnes connaissances en Java)

    Je bloque sur un exercice qui n'a pas l'air difficile:

    voici le contexte :
    Je dispose d'une classe abstraite Vehicule et de deux sous classes Voiture et Moto.

    Voici la question
    Creez une nouvelle classe Garage contenant des vehicules (moto+voitures)

    Il faudra se servir de la classe template list< >
    Il y a deux façons de proceder (mais vous ferez la deuxième méthode)

    1) le plus simple serait de créer une classe garage possédant une liste de vehicules (comme instance)

    Cette méthode est la plus simple mais vous devrez définir toutes les méthodes servant à la gestion d'une liste de véhicules (ajout, suppression , tri en fonction de l'immatriculation , tri en fonction du nom de propriétaire...)

    2) vous pouvez aussi créer une classe garage qui devra hériter d'une liste de véhicules (la liste est alors héritée de la classe parente)

    Cette méthode est plus rapide car vous heriterez des méthodes déjà implémentées de list

    Il vous est demandé d'utiliser la deuxième méthode !
    Je trouve la première méthode assez simple (je vois bien comment faire)
    Cependant pour la seconde je suis un peu coincé sur la synthaxe:

    Si j'ai bien compris ma classe garage sera une sous classe de list<Vehicule>
    J'ai essayé un bon nombre de syntaxes differentes telles que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class Garage<Vehicule> : list<Vehicule>
     
    class Garage : list<Vehicule>
     
    class Garage<Vehicule> : list
    mais rien ne compile

    Auriez vous une petite idée?

    Merci beaucoup

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Salut,

    je dirais surtout que les énoncés sont au mieux évasifs, inducteur d'erreurs, si ce n'est carrément faux.
    Vehicule est abstraite, tu ne peux pas avoir un std::list<Vehicule>
    Tu pourras avoir tout au mieux un std::list<Vehicule*>. A vrai dire tu pourras avoir que ça.

    Je suppose que ce qu'il attend c'est un class Garage : public std::list<Vehicule*> {};. Rien ne l'interdit, faut juste être conscient que std::list n'a pas de destructeur virtuel.
    Mais bon c'est un peu naze, autant avoir un simple typedef/using à ce niveau.

    une liste de vehicules (comme instance)
    Je suppose qu'il voulait dire "comme membre". Vraiment mal écrit cet énoncé..
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Ou pour résoudre l’absence de destructeur virtuel, on peut aussi utiliser class Garage : public std::list<std::shared_ptr<Vehicule>> {};

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 33
    Par défaut
    Merci beaucoup

    Effectivement j'aurais fait d'emblée la première méthode ^^
    Je vais tenter ce que vous dites et je verrai comment m'en sortir

  5. #5
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    @ Bousk, il est peut être question d'héritage privé ici ? Enfin pour moi "hériter de la STL" et "héritage privé" sont quasiment synonymes.

    Maintenant est-ce-que l'héritage privé a un réel avantage par rapport à l'agrégation ici ? Je pense pas, c'est une façon de penser plus Java (encore qu'en Java on aurait un héritage publique) que C++ : en Java / C# on privilégie l'héritage, en C++ on privilégie l'agrégation.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Ou pour résoudre l’absence de destructeur virtuel, on peut aussi utiliser class Garage : public std::list<std::shared_ptr<Vehicule>> {};
    Je vois pas trop ce que tu espères résoudre comme "problème d'héritage sans destructeur virtuel" avec ça
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Je vois pas trop ce que tu espères résoudre comme "problème d'héritage sans destructeur virtuel" avec ça
    La destruction de la liste va automatiquement détruire tous ses éléments et libérera proprement tous les shared_ptr donc tous les Vehicule qui eux doivent avoir un destructeur virtual.
    Alors qu'en utilisant une liste de pointeurs, on aurait besoin d'intercepter la destruction de liste dans ce cas pour libérer les Vehicule.

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par dalfab Voir le message
    La destruction de la liste va automatiquement détruire tous ses éléments et libérera proprement tous les shared_ptr donc tous les Vehicule qui eux doivent avoir un destructeur virtual.
    Alors qu'en utilisant une liste de pointeurs, on aurait besoin d'intercepter la destruction de liste dans ce cas pour libérer les Vehicule.
    Merci je sais à quoi sert le shared_ptr... Mais ça n'a toujours rien à voir avec le problème de l'absence de destructeur virtuel sur std::vector.

    @ Bousk, il est peut être question d'héritage privé ici ? Enfin pour moi "hériter de la STL" et "héritage privé" sont quasiment synonymes.
    Dans le cadre d'un cours, je pense pas. L'héritage privé est si peu utilisé en pratique, je n'ai jamais embêté mes étudiants avec ça perso. Comme l'héritage protected, 1 slide, 5mn pour dire "ça existe et ça sert à rien", on passe à la suite qui est utile.
    Hériter de la STL n'a rien de sorcier ou maudit, il suffit de ne jamais allouer dynamiquement le conteneur et le manipuler en tant que classe de base lors de sa destruction. En pratique encore je n'ai jamais rencontré de new MyVector où MyVector dérive de std::vector.
    L'intérêt de dériver de std::vector c'est d'avoir une interface simple déjà faîte, et d'y ajouter quelques trucs qu'on trouve utile. Si on veut pas juste manipuler un vector et avoir les fonctions de manipulation externe, ce qui revient dans 99% des cas au même.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  9. #9
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut, et bonne année
    Citation Envoyé par dalfab Voir le message
    La destruction de la liste va automatiquement détruire tous ses éléments et libérera proprement tous les shared_ptr donc tous les Vehicule qui eux doivent avoir un destructeur virtual.
    Alors qu'en utilisant une liste de pointeurs, on aurait besoin d'intercepter la destruction de liste dans ce cas pour libérer les Vehicule.
    Le problème, ce n'est pas le fait que la destruction de la liste occasionne la destruction des véhicules qu'elle contient, mais c'est que si Garage hérite de std::list, on peut -- en vertu du LSP -- décider de ne connaitre une instance de type Garage que comme étant (un pointeur sur) une instance de type std::list, et donc envisager d'avoir un code qui ressemblerait à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class Garage : public std::list<std::unique_ptr<Vehicule>>{
        /* ...*/ 
    };
    int main(){
        std::list<std::unique_ptr<Vehicule>>  * g = new Garage;
        /* ... */
        delete g;
        return 0;
    }
    Or, le fait que le destructeur de std::list ne soit pas virtuel présentera un très sérieux problème : lors de l'appel à delete g;, seul le composant "std::list<std::unique_ptr<Vehicule>>" de notre classe Garage sera détruit -- alors que l'on serait en droit de s'attendre à ce que tout ce qui fait partie de la classe Garage le soit -- ce qui pourrait occasionner de très sérieux problèmes par la suite (même si mon exemple ici est suffisamment simple pour les éviter sur la plupart des architectures actuelles).

    Alors, il est vrai que, avec la classe Garage que je présente, un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main(){
        Garage g;
        /* ... */
        return 0;
    }
    ne posera absolument aucun problème, vu que l'on connait notre garage comme étant... un garage. Mais, comme l'héritage public est destiné à nous permettre de substituer un élément du type dérivé partout où l'on s'attend à obtenir un élément du type de base, on ne peut tout simplement pas prendre le risque que l'utilisateur de notre type Garage ne soit tenté de travailler avec un (pointeur ou une référence sur un) objet qu'il connait comme étant de type std::list.

    Car il ne faut pas oublier la loi de Murphy : si tu laisses la possibilité à quelqu'un de faire une connerie, tu dois t'attendre à ce qu'il la commette forcément tot ou tard, et ce sera toujours au pire moment possible.

    Dés lors, la règle de base est : on ne fait JAMAIS dériver (publiquement) une de nos classes personnelles d'une collection proposée par la bibliothèque standard!

    Certains seront sans doute tentés de trouver des exceptions à cette règle (après tout, chaque règle a ses exceptions, non ) mais aucune exception ne sera admise pour la cause face à cette règle, qui doit être gravée dans le marbre
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. tri de liste chainée
    Par RezzA dans le forum C
    Réponses: 7
    Dernier message: 26/01/2003, 20h25
  2. Réponses: 2
    Dernier message: 04/10/2002, 09h13
  3. liste d'objets
    Par Pierrot dans le forum Langage
    Réponses: 2
    Dernier message: 27/09/2002, 09h56
  4. Compter le nombre ligne listée (COUNT) ?
    Par StouffR dans le forum Langage SQL
    Réponses: 7
    Dernier message: 02/09/2002, 09h41
  5. Listes déroulantes liées entre elles
    Par denisC dans le forum Général JavaScript
    Réponses: 0
    Dernier message: 27/07/2002, 15h53

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