2010-11-11 8 views
2

Comme le titre décrit, j'ai 3 classes:Comment éliminer une copie de variable dans la classe de base avec héritage multiple?

#include <iostream> 

using namespace std; 

class first 
{ 
protected : 
int data; 
public : 
first() 
    :data(1) 
{ 
    // empty 
} 

}; 

class second : public first 
{ 
protected : 
double x; 
public : 
second() 
    :first() 
{ 
    // empty 
} 
}; 

class combine : public first, public second 
{ 
public : 
combine() 
{ 
    // empty 
} 

}; 

int main() 
{ 
combine c; 
cout << sizeof(c) << endl; 

return 0; 
} 

Quand je vérifie le sizeof (premier) est de 4 qui font sens pour moi. Mais je ne sais pas pourquoi sizeof (second) est 16 (j'ai supposé 4 + 8 = 12! = 16), et sizeof (combine) est 24 (4 + 4 + 8 = 16! = 24). Quelqu'un pourrait-il m'aider à expliquer cela? En outre, lorsque « combinent » multiples hérite de « premier » et « deuxième », je compris que sa taille comprend deux données (int) à partir de « premier » et de la classe « deuxième » ; ce qui est un gaspillage de mémoire. Existe-t-il un moyen de contourner ce problème, c'est-à-dire que «d'abord» et «deuxième» partagent une copie de «données»?

+0

vous pourriez être intéressé par ce [proposition de la pile-échange] (http://area51.stackexchange.com/proposals/11464/code-review?referrer=aWNm_PdciyFqjFW8CUacGw2 "Code Review"). – greatwolf

Répondre

5

C'est ce que l'héritage virtuel est pour. Pour garder first d'être dupliqué, partout où vous (directement) dérivez une classe de first, vous devez faire l'héritage virtuel, de sorte que vous auriez:

class second : public virtual first { // ... 

class combine : public virtual first, public second { // ... 
+0

Merci beaucoup Jerry;) – Chan

3

On dirait que l'alignement est réglé sur 8. Ce moyen chaque taille de plus de 8 est arrondie à un multiple de 8. Les tailles inférieures à 8 sont arrondies à 8, 4, 2 ou 1.

  • Première: int = 4.
  • Second: int + double = 4 + 8 = 12, arrondir à 16
  • combiner: int + deuxième = 4 + 16 = 20, arrondir à 24

Et oui, la première :: data est dupliquée dans la combinaison. Utilisez l'héritage virtuel (voir autres réponses) pour résoudre ce problème. Ou ajustez vos relations d'héritage. Cela a pour but d'améliorer les temps d'accès à la mémoire au prix de la mémoire supplémentaire utilisée.

Si vous ne pouvez pas économiser la mémoire supplémentaire, recherchez la magie du compilateur pour définir l'alignement à une valeur inférieure. Heureusement, cela est rarement nécessaire.

+1

Note: Juste pour le rendre explicite. Le compilateur est autorisé à ajouter un remplissage à une classe. Cela est généralement fait pour aligner les objets sur des limites spécifiques de sorte que les tableaux d'objets s'intègrent bien dans les emplacements et soient efficaces pour les accès. –

+0

Merci beaucoup;) – Chan

+0

@Martin Merci pour le commentaire! – Sjoerd

Questions connexes