2017-07-21 2 views
1

Hé, je suis en train de comprendre comment la taille du travail de classe quand je suis en utilisant l'héritage, donc j'écrit ce code:Quelle est la taille de la classe lors de l'utilisation de l'héritage?

class AA 
{ 
public : 
    int a; 
    virtual int getSize() {return sizeof(*this);} 
}; 

class BB : public AA 
{ 
public : 
    int b; 
    virtual int getSize2() {return sizeof(*this);} 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    AA aa; 
    BB bb; 
    std::cout << "Class AA : " << aa.getSize() << std::endl; 
    std::cout << "Class BB : " << bb.getSize() << std::endl; 
    std::cout << "Class BB : " << bb.getSize2() << std::endl; 
} 

La sortie de ce code est:

Class AA : 8 
Class BB : 8 
Class BB : 12 

Ma question est: pourquoi la deuxième sortie renvoie la taille de AA au lieu de retourner la taille de BB? bb c'est le type BB, donc je m'attendais à 12 au lieu de 8?

+0

"pourquoi le résultat bla" est presque toujours une mauvaise question; une meilleure question serait: «Mon intention était de blâmer, selon ma compréhension, blah bla bla, et puis bla suit, mais ça ne marche pas dans la pratique, comment est-ce que mon raisonnement sur bla n'est pas correct?" – curiousguy

Répondre

2
  1. Les classes n'ont pas de taille. Les objets ont des tailles.

  2. getSize() ne connaît que la taille des objets de type A.

  3. getSize2() ne connaît que la taille des objets de type B.

+4

Les types ont des tailles.' Sizeof (AA) 'serait légitime –

+0

@ FrançoisAndrieux: Cela signifie simplement" taille d'un objet de type 'AA' ".Il ne fait pas que le type ait une taille – Deduplicator

+3

@Deduplicator Bien sûr, Je vous accorde que "taille d'un objet T" est équivalent à "taille de type T" quand on parle de C++, mais je ne vous accorderai pas que la deuxième formulation est incorrecte. l'instruction "' int' a une taille de 4 sur ma plate-forme "qui est plus concise que" les variables de type 'int' ont une taille de 4 sur ma plate-forme" .Décrivant un type, la taille est une caractéristique omniprésente ou non c'est explicitement reconnu par la norme.Corriger quelqu'un pour utiliser la première formulation est, je crois, inutilement pédant –

2

Vous ne substituez getSize() en BB si bb.getSize() appelle AA::getSize() et renvoie la taille de bb partie AA. Pour obtenir le comportement que vous attendiez, vous devez ajouter

int getSize() {return sizeof(*this);} 

dans BB.


Pour obtenir plus en détail lorsque vous faites

bb.getSize() 

qui obtient traduit à BB::getSzie(bb). Nous appelons donc la fonction BBgetSzie() et nous lui passons l'objet à utiliser. Puisque BB ne remplace pas getSize() la fonction qui est choisie est AA::getSize(). Nous passons donc la fonction bb à AA. AA la version de la fonction prend un AA& donc dans la fonction this a le type AA même si nous lui avons donné un BB. C'est pourquoi il imprime la taille de AA. Vous devez ajouter le remplacement dans BB de sorte que quand il appelle la fonction le type statique de this est BB et alors vous pouvez obtenir la taille BB.

+0

vous répondez n'explique pas ** pourquoi **. La réponse à laquelle je suis lié (comme je crois que celui-ci est direct duplicate of) donne beaucoup plus d'informations OP l cherche. –

+2

@MarcinOrlowski Comment ne pas expliquer pourquoi 'bb.getSize()' renvoie la même chose que 'aa.getSize()'. Je ne vois pas comment votre question que vous suggérez comme dupe est une dupe pour cette question. – NathanOliver

+0

@JesperJuhl * "La raison en est que la fonction fonctionne sur une instance de' AA'. "* - Ce n'est pas vrai, le type de' * this' est toujours 'BB', et si vous appelez la fonction virtuelle' ' getSize() ', vous appelez le remplacement de' BB', la vraie raison est que 'sizeof()' est une valeur de compilation, et au moment de la compilation 'decltype (* this)' 'getSize()' est 'AA &'. – Holt

3
virtual int getSize() {return sizeof(*this);} 

Bien que nous ne pensons pas toujours comme tel, sizeof calcule sa valeur à la compilation, pas l'exécution. Donc, vous pourriez aussi bien penser à cette fonction qui ressemble à ceci:

virtual int getSize() {return 8;} 

qui vous évidemment attendez pas à changer quand hérité dans une autre classe.

La façon de s'assurer que les classes dérivées renvoient la bonne valeur est de s'assurer qu'elles écrasent cette fonction avec la taille de leur classe respective.

+0

C'est l'IMO la meilleure réponse qui adresse directement le problème d'OP - 'sizeof' calcule sa valeur lors de la compilation. – Holt