Рассмотрим следующий код:
struct A
{
int i;
float f;
};
struct B : A
{
char c;
};
Подскажите, пожалуйста, есть ли гарантия того, что c
располагается в памяти строго за f
. Причем, точно таким же образом, как если бы эти члены изначально находились в одной структуре?
Также мне интересно, если B
не будет являться POD
типом, измениться ли что-то в расположении c
в памяти?
Поля класса с одним уровнем доступа располагаются строго последовательно:
12.2 Class members [class.mem]
18 Non-static data members of a (non-union) class with the same access control (Clause 14) are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified (Clause 14).
Расположение базовых подъобъектов неспецифицировано:
13 Derived classes [class.derived] 5 The order in which the base class subobjects are allocated in the most derived object (6.6.2) is unspecified.
Однако для standard-layout классов адрес объекта обязательно совпадает с адресом первого поля и / или с адресом первого подъобъекта:
12.2 Class members [class.mem] 25 If a standard-layout class object has any non-static data members, its address is the same as the address of its first non-static data member. Otherwise, its address is the same as the address of its first base class subobject (if any).
Из этого всего следует, что с
в классе B
не обязательно будет располагаться за f
так как класс B
не является standard-layout классом, а вот если бы оно было объявлено после f
в классе A
, то тогда было бы обязательно расположено строго после f
и в памяти.
Члены класса(структуры) конструируются и распологаются по такому же порядку, по которому они были объявлены( порядок иниуиализации не имеет значения). Значит, в структуре А
, как сказано в 12.2 Class members [class.mem]
, приведенной user7860670
, элементы обьекта будут распологаться строго по порядку:
обьект A() -> | i | f |
Тут адрес A()
совпадает с адресом i
, как сказано в 12.2 Class members [class.mem] 25
.
Обьекты типа В
, будут иметь один подобьект базового класса А
, это значит, что на его основании лежит объект А()
+ у него еще есть член char c
, который расположится после обьекта А()
.
обьект В() -> | A() | c |
Это значит, что с
, в классе В
, в данном случаи, обязательно будет распологаться после f
обьект В() -> | i | f | c |
Но, если есть наиболее производный обьект (most derived object), например:
struct D {
int m{};
};
struct most_derived : D, B {};
most_derived md_obj;
который имеет подобьект типа А
, подобьект типа В
(который в свою очередь имеет подобьект типа А
) и подобьект типа D
И вот тут : порядок расположения подобьектов (D() и В()
), в наиболее производном обьекте ( md_obj
) для базового класса А
, не определен,следовательно в обьекте md_obj
порядок следования m
и с
, не определено(в частности &md_obj
будет совпадать с &m
или с &i
?... неизвестно) _ вот о чем говорится в
13 Derived classes [class.derived] 5
.
Вывод: если В
является не POD
типом, расположение с
всеравно не изменится, оно может изменится только в другом не POD
типе _ таком, как most_derived
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть структура _dem_ram_data_Она должна занимать в памяти 16 байт, но я получаю 21 байт
Есть приложение с областью, которая реагирует на клик мышки:
Числовая последовательность называется пилообразной если каждый ее член (кроме первого и последнего) либо больше обоих своих соседей, либо...
Установка пустого атрибута ACCESS_EXTERNAL_DTD вызывает исключение "не поддерживается: http://javaxxml