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 :

Problème de mémoire sur un objet hérité d'une classe abstraite


Sujet :

Langage C++

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Problème de mémoire sur un objet hérité d'une classe abstraite
    Bonjour,

    Je m'entraîne à la POO en me faisant une librairie de calcul sur des Points dont le type de base est laissé vaquant (template T).
    J'ai donc fait une classe de base Point, entièrement abstraite (pas de variable membre, que des méthodes publiques abstraites). Puis j'ai dérivé cette classe en une Classe Vector, contenant aucune variable mais avec des méthodes publiques non abstraites. Enfin, j'ai dérivé de Vector des classes implémentables, avec ce qu'il faut de variables, implémentant toutes les méthodes abstraites et surchargeant certaines méthodes de Vector. Par exemple, une classe Point3D, avec x,y et z comme variables de type T.

    Compilation sous Code::Blocks 8.02 sous Windows, environnement natif (donc mingw 3.4.4 il me semble). Pas de warning, tout est ok en debug et en release.

    A l'exécution d'un programme test créant un Point3D<char> et faisant quelques manipulations simples (pour tester mes surcharges des opérateurs courants), je fais afficher sizeof(Point3D<char>).
    A ma grande surprise, il affiche : 8. En mémoire, je vois un joli en-tête de 4o avant les 3o réservés à mes données.


    Alors j'ai simplifié l'architecture globale pour tester ce problème de mémoire. Je garde une seule classe abstraite dont hérite une classe quelconque. Classes template, et 3 variables dans la classe fille de type T.
    Voici le 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
    17
    18
    19
    20
    21
    #include <iostream>
     
    template<class T>
    class prestruct {
    public:
      virtual T& f(int) =0;
    };
     
    template<class T>
    class mystruct : public prestruct<T> {
    public:
      T x,y,z;
    public:
      T& f(int i)
      { return x; }
    };
     
    int main(int carg, char** varg) {
      cout << sizeof(mystruct<char>); << endl;
      return 0;
    }
    Quand je lance le code compilé, il m'affiche 8. Même chose, même en-tête.
    Maintenant, quand j'enlève "l'abstraction" de la méthode f de la classe mère, i.e. je code un truc au pif, il m'affiche 3. Plus d'en-tête, juste mes données non alignées sur 32 bits (ce que j'aimerais avoir au final).

    Quelqu'un pourrait-il me dire ce qui se passe ? Est-ce que ma version de gcc est bien trop vielle ? Est-ce un problème de compilo ?
    A noter que les résultats sont les mêmes en release et en débug, qu'en release j'ai enlevé toutes les infos de débogage. J'ai aussi essayé l'option de gcc -fno-rtti, sans succès.

    Merci d'éclairer ma lanterne

  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
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour et bienvenu,
    Les informations rajoutées sont celles nécessaires à l'appel des fonctions virtuelles (en gros, un pointeur sur une vtable). Si tu supprimes toutes tes fonctions virtuelles de la classe de base, tu obtiendras probablement un résultat proche de 3. Une façon de s'en sortir alors est d'utiliser l'idiom CRTP.

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Merci beaucoup 3DArchi.
    Je ne connaissais pas ce concept, j'avoue que c'est sympa !

    Ce que je ne comprends pas, c'est l'utilité des infos de virtualité à l'exécution. Je croyais que tout était décidé à la compilation, donc dans ma tête, je pensais que le compilo faisait directement un jump à l'adresse du bloc d'instructions correct.

    Finalement, si je comprends bien, il ne faut pas utiliser la virtualisation si on fait attention à la mémoire et/ou à la vitesse d'exécution.

    En tout cas, merci beaucoup !!

    EDIT : j'ai lu les infos sur le Type Erasure, je comprends l'intérêt des infos de virtualisation pendant l'exécution. La virtualisation est donc à utiliser avec parcimonie ...

  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
    Points : 13 017
    Points
    13 017
    Par défaut
    Définir une fonction comme virtuelle permet d'avoir une résolution de l'appel selon le type dynamique de l'objet : voir cette réponse et la suivante ainsi que les liens vers la F.A.Q proposés.
    Ensuite, c'est une question de sémantique de tes classes (valeur ou entité). A la base, je pense que tu as un problème : la classe point ne devrait pas être une classe de base pour la dérivation car elle ressemble plus à une classe avec une sémantique de valeur. La classe Vecteur devrait probablement aussi avoir une sémantique de valeur et contiendrait par valeurs un ensemble de point.
    La classe Point3D pourrait dériver de la classe Vecteur mais en privée pour bénéficier de l'implémentation et comme alternative à la composition (cf Quand dois-je faire un héritage public ? protégé ? privé ?).
    En tout état de cause, une classe de base qui ne contiendrait aucun membre virtuel et qui servirait de base à une dérivation publique, je m'interrogerais sur cette conception car j'ai l'impression que dans beaucoup de cas ce sera une erreur (d'autant si la classe a vocation à être détruite de façon polymorphe).

Discussions similaires

  1. Problème d'actionListener sur un objet java3D
    Par Hipopopol dans le forum Débuter
    Réponses: 0
    Dernier message: 11/12/2008, 16h23
  2. Problème espace mémoire sur module
    Par gege91 dans le forum AS/400
    Réponses: 4
    Dernier message: 26/11/2008, 17h15
  3. Mémoire sur l'objet en PHP / ASP / .NET
    Par arnaudperfect dans le forum ASP
    Réponses: 9
    Dernier message: 22/08/2007, 18h48
  4. Problème de surcharge sur mon objet
    Par MasterFunk dans le forum ASP.NET
    Réponses: 9
    Dernier message: 06/06/2007, 13h59
  5. Réponses: 2
    Dernier message: 05/05/2007, 16h57

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