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 :

Erreur d'héritage, membre non trouvé


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut Erreur d'héritage, membre non trouvé
    Salut les C++,

    Cette nuit j'ai tenté de coder une mini-classe de base (un membre, une méthode) dont d'autres classes devaient hériter.
    Et j'ai codé, naturellement sans me poser de questions, pratiquement le même bout de code suivant, au type du membre et de la méthode près :

    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
    class Base_Test {
     
      public :
     
        int m_int ;
     
        Base_Test() {} ;
     
        int get_int() { return m_int ; } ;
    } ;
     
    class Test : public Base_Test {
     
      public :
     
        Test(const int integer) ;
    } ;
     
    Test::Test(const int integer) : m_int(integer) {
     
      /** etc.. **/  
      ;
    }
    Et le compilateur (g++ -std=c++11 testit.cpp ) a renvoyé le message d'erreur suivant :

    testit.cpp: In constructor ‘Test::Test(int)’:
    testit.cpp:19:33: error: class ‘Test’ does not have any field named ‘m_int’
    Test::Test(const int integer) : m_int(integer) {
    Bon. Étant débutant mais quand même (3 mois de C++) je me suis dit que si les 23 lignes qui sont censées définir une classe dont une autre hérite me viennent pas naturellement je devais avoir un problème avec l'héritage de classe défini personnellement, ce pourquoi je poste.

    Car je me sens frustré de cet mini échec, vous me direz c'est pas compliqué : merci, je sais. J'ai déjà fait ça, de l'héritage avec du C++, notamment des jeux avec gtkmm entre autres.

    J'aurais pu rapidement trouver la solution à mon problème tout seul mais je me soucie du mauvais réflexe ou plutôt de ce qui manque, je suppose, dans la définition des classes.

    Alors je voudrais que vous m'aidiez à comprendre ce qui ne va pas dans mon code (réflexe) car si je dois coder une dans une situation d'héritage je referai la même erreur, je pense, si vous ne me corrigez pas. Ce pourquoi je poste.

    Merci pour votre aide précieuse.



    Une autre chose plus intéressante à débattre:

    J'aimerais savoir (ou avoir votre avis) sur le fait de soit:

    1. mettre une variable en membre private et implémenter des accesseurs.
    2. mettre une variable en membre en public et y accéder directement.

    Car j'ai souvent lu | vu qu'il faillait préférer la première solution.

    Il n'y a aucun problème pour moi, mais j'aimerais savoir d'où vient ce conseil ou plutôt quel sont les avantages de la première solution.
    Il faut dire que je n'ai pas encore lu de bouquin sur comment coder correctement ou de manière optimiser en C++: les bon usages brefs.

    Alors est-ce:

    1. Pour des question de clarté de code ?
    2. Pour des raisons de performances ?
    3. Se protéger contre soit-même (c'est débile) ?
    4. Ce sont les usages ?

    Bref : pourquoi se compliquer la vie avec 2 méthodes de plus (qui sont souvent définies dans la déclaration de la classe, donc considérées comme des méthodes inline par le compilateur) et qu'a l'espace private de plus ?

    J'aimerais comprendre le pourquoi du comment, bref ce qui se cache sous le capot.

    Merci pour vos réponses éclairées et l'aide apportée.

    Bon code C++ à vous.

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    m_int est membre de la classe de base, elle-même membre de la classe héritée.
    Tu ne peux pas l'initialiser ainsi, car il a déjà été initialisé par le constructeur par défaut.

    Tu ne peux plus que le réinitialiser.

    C'est pourquoi tu voudras probablement définir un constructeur tel que Base_Test(int i) : m_int(i) {}, qui sera protected ou public, selon le reste des besoins.

    Et ton constructeur de classe héritière sera ainsi fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Test::Test(int integer) : Test_base(integer) {
        //...
    }
    Note que tu n'as pas besoin de définir l'argument comme constant si tu le prends par copie.

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Pour les questions de private/public.

    Il faut bien distinguer le développeur qui conçoit une classe de celui qui l'utilise, ca peut être la même personne, mais pas avec le même objectif.

    L'interface publique est extrèmement sensible, c'est avec elle que sera écrit le code utilisant ta classe.
    L'espace privé permet de faire tout ce que tu veux, sans crainte de casser du code si tu dois changer.

    Une variable membre publique n'est pas maitrisée par la classe. Possédée, oui, mais pas maitrisée.

    Une autre distinction, c'est que les fonctions publiques disent ce que l'objet fait, les services qu'il rend.
    Tandis que les fonctions privées expriment des détails de comment il le fait.

    Tu n'as aucune envie de savoir que pour poster ta réponse, tu vas devoir passer par des requêtes HTTP, DNS, des protocoles comme IP, TCP ou UDP, Ethernet etc.
    Par contre, le fait de pouvoir mettre du texte en gras, en italique, ou du code, ça, oui, ça t'intéresse.

    Une classe (au sens POO) sert à masquer des détails techniques pour s'intéresser à un problème de plus haut niveau.
    Par contre, c'est vrai, une classe peut aussi servir de "paquet de données cohérentes", à la façon d'une struct en C.

    Je précise en C, car en C++, struct et class sont quasiment synonyme. Et même parfaitement synonyme si tu précises systématiquement (pour lisibilité) les private: etc

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 754
    Par défaut
    Je ne m'y connais pas trop en C++, mais ton code selon les différents modèles que j'ai pu voir pourrait prendre cette forme

    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
    #include <iostream>
     
    using namespace std;
     
    class Base_Test {
     
      public :
     
        int m_int ;
        Base_Test() {} ;
     
        int get_int() { return m_int ; }
    };
     
    class Test : public Base_Test {
     
    public:
     
        Test(const int);
     
    } ;
     
    Test::Test(const int integer) : Base_Test() {
     
      /** etc.. **/
     
      ;
    }
    Il n'y a aucun problème pour moi, mais j'aimerai savoir d'ou vient ce conseil ou plutôt quel sont les avantages de la première solution.
    Avantage, non, mais un intérêt plutôt conceptuel je pense, dans le sens où les membres privés ne sont pas accessibles depuis du code en dehors de la classe.
    Pour l'héritage, franchement ça me gênerait, et je choisirais plutôt à utiliser des membres protégés (protected), inacessibles en dehors d'une classe, mais équivalents à des membres publics. Enfin bref, lire cela...

    C'est sans doute une question de performance aussi de ne pas utiliser les membres privés quand on fait de l'héritage, car moins flexible...

    En ce qui me concerne, il est logique que tu te poses cette question dans le cas de l'héritage, les membres privés étant contraignant dans ce cas de figure.

    Je pense avoir dis ce que je peux selon ma faible expérience en C++

  5. #5
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Dans le cadre de l'héritage, il convient de se poser la question parfois délicate de pourquoi faire de l'héritage.

    Une classe est-elle pensée pour servir de classe de base? si oui, il faut réfléchir à ce qu'elle propose.
    En C++, on dispose de deux formes d'héritages (et de moyens de ne pas le faire du tout ).

    L'héritage public, ou apparant, sert à exprimer le fait qu'un Bidule est aussi un Truc, et que tout ce qui accepte un truc peut tout aussi bien accepter un Bidule. Si ca n'est pas le cas, alors soit Bidule, soit Truc est mal conçu.
    Et la réponse est pratiquement toujours que c'est Bidule qui n'aurait pas dû être un Truc.

    L'héritage privé, ou technique, sert à hériter d'une classe technique.

    Une classe Logger qui sert à faire des logs aurait intérêt à paraitre comme un std::ostream. Cela permettra à chaque utilisateur de ne pas redéfinir des fonctions spéciales pour logger ce qui leur plaira. Du moins, pas une seconde série à cote de celle pour un fichier ou le flux standard.

    Un héritage privé souvent une alternative à une composition (le fait d'avoir un membre), mais n'est absoluement pas perceptible par l'utilisateur de la classe.
    En général, toute fois, l'héritage n'est pas conseillé.

    Pour être tout à fait honnête, il existe une troisième forme d'héritage, l'héritage protected. Cela permet aux classes héritières de la classe héritante (les petites filles, donc), de savoir que l'héritante est construite autour de la classe de base, mais cache ce même fait aux simples utilisateurs.
    Je n'en connaissais aucun usage jusqu'a présent. Je viens de découvrir que boost::compressed_pair s'en sert.

  6. #6
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut
    Merci les gars pour les nombreuses réponses et explications que vous avez fournis.

    Concernant le premier problème, le problème d'héritage, j'ai pus le résoudre en quelques minutes quand j'ai repris le code.
    Disons que j'ai un peu flipper quand j'ai vue que je rencontrai des problèmes avec quelques lignes de code vraiment basiques et que j'ai fait un flan pour rien quand j'ai remarquer ce mauvais réflexe qui est en faîte une erreur de ne pas initialiser le membre dans le constructeur de la classe de base et avoir fait l'erreur de ne pas appeler celui-ci dans la classe héritée...

    Mais ça a eu l'avantage de susciter chez vous de nombreuse réactions concernant l'héritage, vos réponses sont fort intéressantes, merci.

    Par contre je n'ai eu que peu de réponses concernant le deuxième débat ou du moins pas celle que j'attendais.

    Vous avez donc dit si je résume que l'espace private permet de masquer certains membres ou méthodes de classe dans les tout les cas mais surtout pour l'interface de la classe: private on touche pas et c'est sur. Par contre publique c'est ce qui est faisable avec la classe et du coup moins sur.

    Mais apparemment personne n'a entendus parler de ce conseil de codage de préféré les membres privée avec getters et setters plutôt que un membre a accès directe déclaré dans l'espace publique...???

    Car un getter ou setter peu faire aussi autre chose que de simplement affecter ou renvoyer la valeur d'un membre:

    Contrôle de marge maximale et minimale de valeurs par exemple
    ou ce qui va influer sur les autres membres de ce changement de valeur dans le cas d'un setter.


    Donc si ce n'est pas si répandus que ça je ne dois pas m'inquiéter de ce qui se cache derrière ce conseil.

    Je pensais seulement que c'était un conseil comme d'éviter le plus possible les variables globales en C.
    Plutôt passer des pointeurs de fonction en fonction par exemple a la place (a ne pas faire en C++ je pense).
    PS: j'ai récemment découvert le fond de la notion de fonction inline:

    Le mot-clef inline suggère au compilateur de copier et d'exécuter le code de la fonction inline directement a l'endroit ou la fonction inline est appelée a la place de placer la fonction sur la pile comme une fonction classique.

    Quel sont les avantages: éviter un empilement.

    Quand utiliser le mot-clef inline: pour de petites fonctions que l'on appelle souvent dont le code peut être remplacer par quelques lignes de codes analogue a l'endroit de l'appel.

    Quand ne pas utiliser le mot-clef inline: par exemple pour des fonctions récursives, vous comprendrez sûrement pourquoi.

    J'en vient au faîte:

    Existe-t-il une manière de faire savoir au compilateur qu'une variable va souvent changer de valeur afin que le compilateur puissent optimiser en conséquence ?

    Et si oui quel est le nombre moyen de changements de valeur acceptable afin de signifier cela au compilateur par rapport aux nombre d'instructions ?
    Car sinon l'on en mettrai dans toutes les variables de compteurs de boucles...

    Au cas ou vous ne le sauriez pas: il existe des types (contenus dans inttypes.h en C mais présent par défaut en C++) qui sont bien pratiques:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int8_t    == char
    uint8_t   == unsigned char
     
    int16_t   == short
    uint16_t  == unsigned short 
     
    int32_t   == int
    uint32_t  == unsigned int
    Connaissez vous d'autres typedef autant pratique et que pratiquement tous les éditeurs de texte colorent (le mien en tout cas oui et la coloration syntaxique de developpez.net aussi) ce qui n'est vraiment pas le cas de tous les typedef...

    Sur ce bon code C++ a vous.

  7. #7
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Dans le long débat, très sujet à trolls, du get/set face à la variable publique, on a diverses positions, qui se tiennent.

    La réponse ultra prudente:
    Toute variable membre est privée, sa visibilité est gérée par celle de ses get/set.
    L'intérêt premier est de pouvoir établir des controles, notamment dans la fonction set.
    Ainsi, tu pourrais avoir une classe de nombre pair, dont le set serait écrit ainsi: void setValeur(T i) {internal = i - i%2;}Si jamais il faut subitement ajouter un controle, il n'y a pas besoin de modifier tout le code pour introduire des fonctions.

    get et set ne devrait pas faire de controles
    Dans l'idée, get et set ayant une signification précise en langue humaine (ici, l'anglais), il doivent la respecter.
    De la même manière que Integer operator+(Integer, Integer) est priée de retourner la somme des valeurs que représente ses arguments.

    Du coup, get+set publiques signifie une variable publique.

    get et set sont souvent des erreurs de conception
    Si effectivement ils ne font pas de controles, et sont publiques, alors ce sont des obstacles à la lisibilité.
    Et souvent, d'autres noms sont plus parlant.
    Prenons une classe de point. On a deux considérations possibles:
    • la posture mathématique: un point est une valeur. Il n'y a pas de fonction de mutation. C'est une structure ouverte, généralement passée par référence constante.
    • le point de vue 2D/3D: un point est un objet, qui peut se déplacer (vertex).

    Dans ce second cas, getX() et getY() sont passablement intéressant (même si je les appellerai plutot x() et y()). Par contre, on ne voudra pas de setX ou setY. On préfèrera moveTo(Point), moveTo(x, y) et moveBy(Vector), moveBy(dx, dy). (moveTo pouvant aussi être nommée placeAt).

    Les getters restent assez intéressants, pour des raisons concrêtes de facilité d'écriture du reste du code.
    Mais je préfère ne pas mettre le mot get, pour ne pas induire que la variable est présente.

    Tu l'auras compris, ma position est de ne pas avoir de setteurs explicite.
    Une classe est soit une valeur (pas de setteurs, mais constructeur et opérateur=), soit une entité, ayant une plus grande sémantique qu'un paquet de variable.

  8. #8
    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,
    Citation Envoyé par fred1599 Voir le message
    Pour l'héritage, franchement ça me gênerait, et je choisirais plutôt à utiliser des membres protégés (protected), inacessibles en dehors d'une classe, mais équivalents à des membres publics.
    A vrai dire, c'est une très mauvaise idée que de mettre des (variables) membres en <codeinline>protected</codeinline>, car cela pose le problème que c'est aux classes dérivées (filles / enfants) de s'assurer qu'elles respectent les invariants de la classe de base (mère).

    Cela pose moins de problèmes avec les fonctions -- virtuelles ou non -- car cela ne fait que permettre à "n'importe quelle fonction membre" de la classe dérivée de faire appel à la fonction définie comme protégée dans la classe de base, sans pour autant permettre de faire appel à cette même fonction depuis l'extérieur.

    Donc, en gros, il est possible d'avoir un code qui serait proche de
    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
     
    class Base{
    protected:
        void foo(/* paramètres*//){
          /* n'importe quoi qui modifie (ou non) les données membres qui
           * se trouvent dans l'accessibilité PRIVEE
       }
    private:
        /* quelques variables, dont on n'a pas besoin d'avoir le détail */
    };
    class Derivee{
    public:
        bar(/* paramètres */){
            foo(/*arguments */); // appelle Derivee::foo()
        }
    };
    et ce code serait très largement préférable à quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Base{
    protected:
     
        /* quelques variables, dont on n'a pas besoin d'avoir le détail */
    };
    class Derivee{
    public:
        bar(/* paramètres */){
            /* modifie les variables protégées de Derivee, au risque de briser les invariants */
        }
    };
    En effet, le premier code t'apportera la garantie que seules les fonctions membre de Base iront modifier les données membres de Base, avec comme effet secondaire très désiré que, s'il y a un bug, nous aurons la certitude qu'il ne faut aller voir que du coté des fonctions membres de Base.
    Par contre, le deuxième code laisse la possibilité aux fonctions des classes dérivées d'aller modifier... les membres de Base, avec comme effet secondaire indésirable le fait que, s'il y a un bug au niveau de Base, nous devrons non seulement vérifier toutes les fonctions de Base, mais aussi toutes les fonctions de toutes les classes dérivées, ce qui risque de faire "un paquet"
    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

  9. #9
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut
    Merci pour vos réponses,

    Concernant l'explication de l'eternel, c'est parfaitement clair maintenant pour moi. Tout autant comme ton explication du principe du RAII qui m'a permis de mieux comprendre ce principe. Merci.

    Tout autant que le code exemple de Iradrille qui démontre une utilisation pratique de template de gestion de RAII, visant a automatiser le RAII.

    C'est enrichissant car cela va peut être me servir dans un futur proche car je me demandais comment forcer la destruction d'une frame: objet de type cv::Mat de la lib OpenCV.


    Concernant le mot-clef register c'est un peu confus pour moi ayant une mini expérience d'un mois d'apprentissage et de pratique de l'assembleur (ce qui s'est avéré très utile malgré que j'ai abandonner ce langage de programmation, simple en terme de logique mais trop de travail pour réellement écrire un programme concret.)
    Car si une variable occupe constamment (le temps qu'elle soit détruite) un registre du processeur ça va sérieusement handicaper le compilateur pour générer le code assembleur...
    Ce qui explique le conseil de ne pas utiliser ce mot-clef.
    Ou ce n'est peut-être pas le cas et peut être existe-t-il d'autres registres que ceux de l'assembleur, qui ne sont pas propre au processeur ?

    Avez vous remarquer que pour désigner regsiter et inline j'utilise le terme "mot-clef" alors que ce type de "mot-clef" font partie d'un ensemble qui porte un vrai nom et non mot-clef.
    Je viens de vérifier et corriger moi si je me trompe mais inline fait partie des: storage class specifier.
    Tout comme static, extern et auto (En C ou < std=c++11),
    qui influent sur le scope, la durée de vie donc et le linkage (je ne comprends pas pour ce dernier).
    Qui peuvent être de 2 types différents: statique et automatique selon mes sources.


    Concernant le spécificateur static je le connais bien:

    - Une variable déclaré comme static locale dans une fonction ne s'initialise que lors du premier appel de la fonction puis peut être modifier lors des d'autres appels (elle ne sera pas remise a la valeur d'initialisation du premier appel.).

    - Une variable déclaré comme static membre d'une classe doit être initialiser en dehors de la déclaration d'une classe (comme la définition une méthode). Et elle a pour particularité qu'il n'existe qu'une seule instance de celle-ci même si il existe plusieurs instance de la classe.

    - Une variable déclaré comme static globale est locale a un fichier de code source.

    Mais j'ai pour lacune, que je vous pris de bien vouloir combler en m'expliquant, pourquoi déclaré une fonction ou une méthode comme static, car je ne sais pas comment cela affecte la fonction ou méthode ???

    Car j'ai souvent vue des fonctions déclaré comme static mais je n'ai jamais compris pourquoi...



    Et j'ai une question pour koala01 car j'ai du mal a comprendre tes 2 exemple de code:
    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
     
    class Base{
    protected:
        void foo(/* paramètres*//){
          /* n'importe quoi qui modifie (ou non) les données membres qui
           * se trouvent dans l'accessibilité PRIVEE
       }
    private:
        /* quelques variables, dont on n'a pas besoin d'avoir le détail */
    };
    class Derivee{
    public:
        bar(/* paramètres */){
            foo(/*arguments */); // appelle Derivee::foo()
        }
    };
    Tu n'a pas fait hériter la classe Derivee de la classe Base et tu appel foo() dans bar() mais de manière Derivee::foo() (externaliser) alors que tu parle de classe de base donc d'héritage ??? Est-ce volontaire ?

    Et dans ton deuxième code je ne vois pas le rapport entre les deux classes.

    Peut-être parle tu de classe de Base abstraite (ABC (Abstract Base Class) ne servant qu'a faire hérité), j'avoue que j'ai du mal a suivre ton code même si tes explications sont claires.

    Merci pour vos réponses éclairées illuminant les ténèbres de mon inexpérience en C++.

  10. #10
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 036
    Billets dans le blog
    12
    Par défaut
    [QWERTY]
    Pour register tu as le bon raisonnement, je pense, ca peut rendre la tache du compilateur plus complexe (mais nous, on s'en fiche hein!)
    Et quant a son utilisation, je ne l'ai utilise qu'une fois, lors de l'optimisation d'un code de conversion de dimensions de video (donc effectue a chaque frame affichee), et ca avait pas mal booste les perf, avant que je ne passe en SSE2 (c'est plus la meme chose )
    [/QWERTY]
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

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

Discussions similaires

  1. Liste des instructions de la bibl. std c++
    Par BBric dans le forum SL & STL
    Réponses: 7
    Dernier message: 29/10/2004, 01h02
  2. Sauvegarde std::vector dans un .ini
    Par mick74 dans le forum MFC
    Réponses: 2
    Dernier message: 12/05/2004, 14h30
  3. Recherche "étoilée" avec std::set
    Par guejo dans le forum MFC
    Réponses: 2
    Dernier message: 06/05/2004, 14h28
  4. std MFC
    Par philippe V dans le forum MFC
    Réponses: 7
    Dernier message: 17/01/2004, 01h54
  5. STL : std::set problème avec insert ...
    Par Big K. dans le forum MFC
    Réponses: 13
    Dernier message: 08/11/2003, 02h02

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