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

Langage C++ Discussion :

Proposition : héritage constant


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut Proposition : héritage constant
    Bonjour,

    Que pensez-vous de l'idée d'un héritage constant en C++ ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class Cercle : public const EllipseAbstraite { /*...*/ };
    Caractéristiques :
    • Cercle& est convertible en const EllipseAbstraite&, mais pas en EllipseAbstraite&.
    • Si EllipseAbstraite a des fonctions virtuelles pures alors, pour que Cercle soit instanciable, il doit implémenter les fonctions virtuelles pures constantes de EllipseAbstraite.
    • Si on appelle une fonction non constante de EllipseAbstraite via une instance de Cercle (à cause d'un const_cast), le comportement est indéterminé.
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      Cercle cercle;
      const EllipseAbstraite& ellipse = cercle;;
      EllipseAbstraite& danger = const_cast<EllipseAbstraite&>(ellipse);
      danger.fonctionNonConstante(); // aïe
      danger.fonctionVirtuellePureNonConstante(); // crash
    • Le code suivant est autorisé :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      class Deriv : virtual public const Base { /*...*/ };
      class Deriv2 : public Deriv, virtual public Base { /*...*/ }; // pas de const
    • Pour la cohérence, on aurait aussi l'héritage volatile et l'héritage constant volatile, qui ne serviraient à rien.


    Le principal intérêt serait de réduire la quantité de classes en évitant les doublons Base/ConstBase :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class EllipseAbstraite : public ConstEllipseAbstraite { /*...*/ };
    class Cercle           : public ConstEllipseAbstraite { /*...*/ };

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Avant de détailler le mécanisme plus en détails, tu pourrais détailler la motivation ? Parce que pour l'instant, je ne vois pas trop ce qu'on y gagne...
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Par exemple, à la place de ceci :
    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
    class Product { /*...*/ };
    class Fruit : public Product { /*...*/ };
    class Orange : public Fruit { /*...*/ };
     
    class ConstProductTable {
    public:
        virtual const Product& getProduct(size_t index) const = 0;
        // ...
    };
     
    class ProductTable : public ConstProductTable {
    public:
        virtual void addProduct(const Product&) = 0;
        // ...
    };
     
    class ConstFruitTable : public ConstProductTable {
    public:
        const Fruit& getProduct(size_t index) const override = 0;
        // ...
    };
     
    class FruitTable : public ConstFruitTable {
    public:
        virtual void addFruit(const Fruit&) = 0;
        // ...
    };
     
    class ConstOrangeTable : public ConstFruitTable {
    public:
        const Orange& getProduct(size_t index) const override = 0;
        // ...
    };
     
    class OrangeTable : public ConstOrangeTable {
    public:
        virtual void addOrange(const Orange&) = 0;
        // ...
    };
    On aurait cela :
    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
    class Product { /*...*/ };
    class Fruit : public Product { /*...*/ };
    class Orange : public Fruit { /*...*/ };
     
    class ProductTable {
    public:
        virtual const Product& getProduct(size_t index) const = 0;
        virtual void addProduct(const Product&) = 0;
        // ...
    };
     
    class FruitTable : public const ProductTable {
    public:
        const Fruit& getProduct(size_t index) const override = 0;
        virtual void addFruit(const Fruit&) = 0;
        // ...
    };
     
    class OrangeTable : public const FruitTable {
    public:
        const Orange& getProduct(size_t index) const override = 0;
        virtual void addOrange(const Orange&) = 0;
        // ...
    };
    Edit 2016-12-19-19h52 (après la réponse de JolyLoic) : J'avais oublié de rendre pures mes fonctions virtuelles.

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Et comment implémentes-tu FruitTable::addFruit ?
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Oups. J'ai oublié de rendre pures les fonctions virtuelles de mon précédent message.
    Code modifié et factorisé :
    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
    class Product {
    	// ...
    };
     
    class Fruit : public Product {
    public:
    	using base = Product;
    	// ...
    };
     
    class Orange : public Fruit {
    public:
    	using base = Fruit;
    	// ...
    };
     
    template<class T>
    class ProductTable;
     
    template<>
    class ProductTable<Product> {
    public:
        virtual const Product& getProduct(size_t index) const = 0;
        virtual void append(const Product&) = 0;
        // ...
    };
     
    template<class T>
    class ProductTable : public const ProductTable<typename T::base> {
    public:
        const T& getProduct(size_t index) const override = 0;
        virtual void append(const T&) = 0;
        // ...
    };
     
    class ConcreteOrangeTable : public ProductTable<Orange> {
    public:
        const Orange& getProduct(size_t index) const override;
        void append(const Orange&) override;
        // ...
    };
    Dans mon exemple, ConcreteOrangeTable& serait convertible en ProductTable<Orange>, en const ProductTable<Fruit>& et en const ProductTable<Product>&.

  6. #6
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Aucun avis ?

    Personnellement, je suis partagé.
    D'un côté, cela permettrait de réduire le nombre de classes dans des cas assez rares.
    De l'autre, cela complexifierait un peu plus le langage C++ qui est déjà compliqué.

Discussions similaires

  1. Héritage de constantes
    Par Troopers dans le forum VB.NET
    Réponses: 4
    Dernier message: 08/03/2009, 18h56
  2. Remerciements, propositions et commentaires
    Par HCath dans le forum Discussions diverses
    Réponses: 57
    Dernier message: 24/08/2006, 10h22
  3. [ADO] Constantes des types de champ
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 05/09/2002, 11h08
  4. Héritage entre Forms
    Par BarBal dans le forum Composants VCL
    Réponses: 7
    Dernier message: 29/08/2002, 17h44
  5. Au sujet des constantes
    Par FranT dans le forum Langage
    Réponses: 8
    Dernier message: 09/08/2002, 11h03

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