Question

Dans les années de C, je suis garanti que:

struct Foo { ... };
struct Bar {
  Foo foo;
  ...
}
Bar bar;
assert(&bar == &(bar.foo));

Maintenant, en C ++, si j'ai:

class Foo { ... };
class Bar: public Foo, public Other crap ... {
  ...
}

Bar bar;
assert(&bar == (Foo*) (&bar)); // is this guaranteed?

Si oui, pouvez-vous me donner une référence (comme "The C ++ Programming Language, la page xyz")?

Merci!

Était-ce utile?

La solution

Il n'y a aucune garantie. A partir de la norme C ++ 03 (10/3, class.derived):

  

L'ordre dans lequel les sous-objets de la classe de base sont réparties dans l'objet le plus dérivé (1,8) est non spécifiée.

Autres conseils

Même si la mise en page pour les classes de base est pas garantie dans la façon dont vous semblez avoir pensé (et même si il y a plus de garanties pour les membres), cela est garanti:

Bar bar;
assert(&bar == (Foo*) (&bar));

Parce que la distribution utilise un static_cast (par 5,4) qui convertira &bar correctement, et la comparaison entre le pointeur à base de pointeur dérivé et convertit la même manière.

Ceci, cependant, ne serait pas garantie:

Bar bar;
void* p1 = &bar;
void* p2 = (Foo*)&bar;
assert(p1 == p2); // not guaranteed

Je ne pense pas que ce serait, je ne sais pas pourquoi il aurait besoin d'être.

J'ai une question connexe.

si vous avez l'héritage de diamant:

class Base(){ virtual void AFunc(){}  };

class A:Base{};
class B:Base{void AFunc(){} }

class Test:A,B{};


Base * b = (Base*)new Test;

b->AFunc();

laisse supposer que la structure de la mémoire est la base: A: B: Test,

note au point d'appeler, tout le compilateur sait est l'adresse du début de l'objet, et AFunc attend d'être par rapport au début de l'objet B, ces deux adresses ne seront pas les mêmes! Alors, comment ça marche?

comme si b était de type B, les deux adresses seraient les mêmes ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top