Pergunta

Em C Struct, tenho certeza que:

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

Agora, em C ++, se eu tiver:

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

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

Se sim, você pode me dar uma referência (como "a linguagem de programação C ++, página xyz")?

Obrigado!

Foi útil?

Solução

Não há garantia. Do padrão C ++ 03 (10/3, classe.Derived):

A ordem em que os subobjetos da classe base são alocados no objeto mais derivado (1.8) não é especificado.

Outras dicas

Mesmo que o layout das classes base seja não garantido Na maneira como você parece estar pensando (e mesmo que haja mais garantias para os membros), isso é garantido:

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

Porque o elenco usa um static_cast (por 5.4) que será convertido &bar Corretamente, e a comparação entre ponteiro para base e ponteiro para derivado será convertido da mesma forma.

Isso, no entanto, não seria garantido:

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

Não imagino que seja, não sei por que precisaria ser.

Eu tenho uma questão relacionada.

Se você tem herança de diamante:

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

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

class Test:A,B{};


Base * b = (Base*)new Test;

b->AFunc();

Vamos supor que a estrutura da memória seja base: a: b: teste,

Nota No ponto de chamada, tudo o que o compilador sabe é o endereço do início do objeto, e o AFUNC espera ser relativo ao início do objeto B, esses dois endereços não serão os mesmos! Então, como isso funciona?

Como se B fosse do tipo B, os dois endereços seriam os mesmos ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top