Вопрос

В C struct, я гарантию, что:

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

Теперь, в C ++, если у меня есть:

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

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

Если это так, вы можете дать мне ссылку (например, «язык программирования C ++, страница XYZ»)?

Спасибо!

Это было полезно?

Решение

Там нет гарантии. Из стандарта C ++ 03 (10/3, класс. Индер):

Порядок, в котором подборки базового класса выделяются в наиболее производном объекте (1.8), не указан.

Другие советы

Хотя макет для базовых классов не гарантировано Таким образом, вы, кажется, думаете (и даже если есть больше гарантий для членов), это гарантируется:

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

Потому что литые используются Static_Cast (за 5,4), которые будут конвертировать &bar Правильно, и сравнение у указателя к базе и указывающему к получению будет конвертировать аналогично.

Это, однако, не будет гарантировано не гарантировано:

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

Я не представляю, что это будет, я не знаю, почему это должно быть.

У меня связанный вопрос.

Если у вас есть алмазное наследование:

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

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

class Test:A,B{};


Base * b = (Base*)new Test;

b->AFunc();

Предположим, что структура памяти является основой: A: B: тест,

Примечание. В точке вызова все компиляторы знают, является адресом начала объекта, а afunc ожидает быть относительным к началу объекта B, эти два адреса не будут одинаковыми! Итак, как это работает?

Как и если B имел тип B, два адреса будут одинаковыми ...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top