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 :

Classe générique et erreur "request for member [..] which is of non-class type"


Sujet :

Langage C++

  1. #21
    Membre expérimenté
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Points : 1 685
    Points
    1 685
    Par défaut
    Bonjour,

    Citation Envoyé par gl Voir le message
    Si mes souvenirs du rôle de extends et d'implements en Java sont bons, j'ai bien peur que la conversion ne soit pas aussi simple et immédiate que cela.
    Je suis d'accord.
    Disons que pour quelqu'un qui est habitué au Java, ça donne un point de repère.
    C'était surtout pour justifier l'emploi du "fonction membre virtuelle pure" pour "méthodes abstraites".

    En outre, l'implémentation d'une interface me semble assez souvent relevé d'un héritage public (le but étant quand même souvent de manipuler l'objet concret au travers de l'interface).
    Une sorte d'héritage public où la classe de base
    - est abstraite,
    - ne contient que des fonctions membres virtuelles pures,
    - dont les données membres sont déclarées const et non privées?

    Ca fait un petit moment que je n'ai pas fait de java mais il me semble que les données membres de l'interface ne sont pas accessibles depuis l'extérieur à partir de la classe qui implémente.
    Si l'accès est possible alors ton point de vue est meilleur que le mien, c'est clair.

  2. #22
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 24
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par gl Voir le message
    Si mes souvenirs du rôle de extends et d'implements en Java sont bons, j'ai bien peur que la conversion ne soit pas aussi simple et immédiate que cela.

    En outre, l'implémentation d'une interface me semble assez souvent relevé d'un héritage public (relation EST-UN dont le but est quand même souvent de manipuler l'objet concret au travers de l'interface).
    J'ai cherché quelques infos sur le net à propos de l'héritage privé. Visiblement, cela modifie la visibilité de touts les membres public/protected de la classe de base en private depuis la classe héritée.

    Je pense que pour créer l'équivalent d'une interface en Java, il faut créer une classe dont tous les membres sont publics et dont toutes les fonctions membres sont virtuelles pures.
    Etant donné que les interfaces en Java sont bien utilisées pour le polymorphisme, il faut à mon sens utiliser un héritage public.

  3. #23
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 24
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Aleph69 Voir le message
    Bonjour,
    Une sorte d'héritage public où la classe de base
    - est abstraite,
    - ne contient que des fonctions membres virtuelles pures,
    - dont les données membres sont déclarées const et non privées?

    Ca fait un petit moment que je n'ai pas fait de java mais il me semble que les données membres de l'interface ne sont pas accessibles depuis l'extérieur à partir de la classe qui implémente.
    Si l'accès est possible alors ton point de vue est meilleur que le mien, c'est clair.
    En Java, une interface ne définie QUE les membres publics. Qu'ils soient constants ou non.

  4. #24
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Il ne faut pas non plus oublier les subtilités permises par les possibilités offertes par C++, CRTP en tête:

    L'héritage public d'une classe template permet de récupérer l'intégralité de l'interface de cette classe de base sans pour autant que deux classes qui en hériteraient ne finissent par se retrouver dans une hiérarchie commune:
    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
    template<CRTP>
    classe Base
    {
        public:
            /* les fonctions "qui vont bien" par rapport à l'interface à fournir */
            void foo();
        private:
           /* les membres "qui vont bien" pour que l'interface fasse ce qu'on
            * attend d'elle
            */
    };
     
    Class Derivee1 : public Base<Derivee1>
    {
        /* tout ce qu'il faut en plus de l'interface de Base ;) */
    };
    class Derivee2 : public Base<Derivee2>
    {
        /* tout ce qu'il faut en plus de l'interface de Base ;) */
    };
    Les classes Derivee1 et Derivee2 disposerons toutes deux de la fonction foo, mais, comme Base<Derivee1> représente un type différent de Base<Derivee2>, il n'y a aucune relation de substituabilité entre les classes Derivee1 et Derivee2.

    Et pourtant, si on complexifie à peine la classe Base (par exemple par adjonction de traits et de politiques), nous obtiendrons de magnifiques comportements polymorphes (même si on parle alors de "polymorphisme paramétrique" )Nous arrivons, il est vrai, dans des domaines de haut vol, mais cela permet de se rendre compte du décalage qu'il peut y avoir entre une explication un peu trop simplifiée et... la réalité du terrain
    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

  5. #25
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par damien.flament Voir le message
    J'ai cherché quelques infos sur le net à propos de l'héritage privé. Visiblement, cela modifie la visibilité de touts les membres public/protected de la classe de base en private depuis la classe héritée.
    Effectivement...

    Tu ne peux d'ailleurs pas essayer de "downcaster" un objet du type dérivé en un objet du type de base qui serait hérité de manière privée.

    L'héritage privé ne représente plus une relation EST-UN mais une relation "EST-IMPLEMNTE-EN-TERMES-DE, et s'apparente beaucoup plus à une composition bien cachée

    Je pense que pour créer l'équivalent d'une interface en Java, il faut créer une classe dont tous les membres sont publics et dont toutes les fonctions membres sont virtuelles pures.
    Etant donné que les interfaces en Java sont bien utilisées pour le polymorphisme, il faut à mon sens utiliser un héritage public.
    La manière la plus proche de créer quelque chose de proche de la notion d'interface en java est en réalité le passage par la programmation générique et l'utilisation du CRTP, comme j'étais occupé à le montrer quand tu as écrit cette réponse
    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

  6. #26
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 24
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Les classes Derivee1 et Derivee2 disposerons toutes deux de la fonction foo, mais, comme Base<Derivee1> représente un type différent de Base<Derivee2>, il n'y a aucune relation de substituabilité entre les classes Derivee1 et Derivee2.
    Citation Envoyé par koala01
    La manière la plus proche de créer quelque chose de proche de la notion d'interface en java est en réalité le passage par la programmation générique et l'utilisation du CRTP, comme j'étais occupé à le montrer quand tu as écrit cette réponse
    Si par "aucune relation de substituabilité" tu entends que l'on ne peut déclarer une variable de type Base<T>, mais seulement Base<Derivee1> ou Base<Derivee2> si on souhaite utiliser le polymorphisme. Alors je pense que l'on s'éloigne d'interface Java.

  7. #27
    Membre expérimenté
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Points : 1 685
    Points
    1 685
    Par défaut
    Re,

    Citation Envoyé par damien.flament Voir le message
    En Java, une interface ne définie QUE les membres publics. Qu'ils soient constants ou non.
    Tu as sûrement raison mais je veux être sûr qu'on s'est bien compris.
    Je vais utiliser le vocabulaire java (méthodes/attributs) puisque tout le monde a l'air de le comprendre.
    Désolé d'avance pour la syntaxe hasardeuse.

    Si on a une interface
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    interface A
    {
        final int entier=0;
    }
    et une classe B
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    class B implements A{};
    et une classe C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    class C extends B{};
    Disons qu'on déclare un objet b de type B et un objet c de type C.
    Est-ce que l'accès b.entier est autorisé?
    Est-ce que l'accès c.entier est autorisé?

  8. #28
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par koala01 Voir le message
    La manière la plus proche de créer quelque chose de proche de la notion d'interface en java est en réalité le passage par la programmation générique et l'utilisation du CRTP, comme j'étais occupé à le montrer quand tu as écrit cette réponse
    Juste par curiosité, quel comportement des interfaces JAVA te pousse à utiliser la programmation générique et le CRTP.

    J'aurais plutôt tendance à les comparer à des classes abstraites ne contenant que des fonctions virtuelles pures et des données membres de classe.


    Enfin bref, mon propos n'était pas de trouver une éventuelle équivalent C++ aux interfaces Java mais de faire remarquer que la correspondance :

    Un héritage public est une extension.
    Un héritage protégé ou privé est une implémentation.
    était trop simpliste.

  9. #29
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 24
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Aleph69 Voir le message
    Re,
    Si on a une interface
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    interface A
    {
        final int entier=0;
    }
    et une classe B
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    class B implements A{};
    et une classe C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    class C extends B{};
    Disons qu'on déclare un objet b de type B et un objet c de type C.
    Est-ce que l'accès b.entier est autorisé?
    Est-ce que l'accès c.entier est autorisé?
    Oui. Lorsque l'on implémente une interface, on se doit de définir toutes les méthodes définies dans l'interface (méthodes publiques, donc). Sachant que la visibilité d'un membre ne peut pas être réduite (seulement augmentée), le membre public défini dans l'interface est donc visible depuis l'extérieur à partir de toutes les classes qui l'implémentent, directement ou indirectement.

    C'est pourquoi à mon sens, si l'on souhaite reproduire le principe d'implémentation d'une interface Java en C++, il est nécessaire d'utiliser un héritage publique.

  10. #30
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par damien.flament Voir le message
    Si par "aucune relation de substituabilité" tu entends que l'on ne peut déclarer une variable de type Base<T>, mais seulement Base<Derivee1> ou Base<Derivee2> si on souhaite utiliser le polymorphisme. Alors je pense que l'on s'éloigne d'interface Java.
    Non, non, non...

    Je parle de sa substituabilité en terme de polymorphisme dynamique.

    Je dis que tu ne peux profiter de la substituabilité pour faire passer un objet de classe A (qui hérite de Base<A> ) pour un type intervenant dans la hiérarchie de la classe B qui hérite de Base<B>, à moins bien sur d'utiliser l'héritage multiple et que A et B héritent toutes deux d'une autre classe commune.

    Par contre, à partir du moment où tu veux utiliser Base<T>, tu peux remplacer T par strictement tout et n'importe quoi, pour autant de respecter d'éventuels prérequis que Base<T> pourrait imposer pour T.

    Si, par exemple (c'est le cas de la STL) tu utilise la copie et /ou l'affectation de T dans ta classe Base<T>, tu auras "fatalement" des problèmes si tu essaye d'utiliser un type non copiable et/ ou non affectable.
    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

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 6
    Dernier message: 25/02/2013, 16h18
  2. Réponses: 2
    Dernier message: 17/02/2013, 20h59
  3. request for member
    Par annesophiedecar dans le forum C++
    Réponses: 2
    Dernier message: 11/10/2009, 21h20
  4. [C] request for member ". . ." in
    Par Meri Nose dans le forum C
    Réponses: 11
    Dernier message: 30/01/2009, 20h03
  5. Réponses: 14
    Dernier message: 14/09/2007, 17h28

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