Public / private / protected изменяют расположение структуры в памяти?

Редактировать: Я только что понял гораздо более простой способ задать этот вопрос:

Учитывая следующие две структуры:

class Thing {public: int a; public: int b; public: int c;}

class Thing {public: int a, private: int b; public: int c;}

Являются ли участники a, b, а также c гарантированно будет в том же порядке в памяти для обоих этих определений?


Старый вопрос

Допустим, у нас есть этот код C ++ в fileA.cpp:

class Thing
{
public:
int a;
double num;

Thing()
{
b = 10;
}

float getB()
{
return b;
}

private:
float b;
Thing * other;
}

void doSomething(Thing thing);

int main()
{
Thing thing;
doSomething(thing);
std::cout << thing.b;
}

И скажем, у нас есть этот код в fileB.cpp:

class Thing
{
public:
int a;
double num;

Thing()
{
b = 10;
}

float getB()
{
return b;
}

float b;

private:
Thing * other;
}

void doSomething(Thing thing)
{
thing.b = 30;
}

Предполагая, что компилятор не будет жаловаться, будет ли этот код работать так, как ожидалось? Является ли расположение данных структуры независимым от того, являются ли определенные компоненты общедоступными, частными или защищенными?

Редактировать: Чтобы сделать это более очевидным, единственное различие между двумя определениями Thing тот факт, что float b; является частным в fileA.cpp но публика в fileB.cpp,

1

Решение

Стандарт не дает такой гарантии. У вас есть гарантии на макет только для стандартных классов:

Класс стандартного макета — это класс, который:

  • не имеет нестатических членов-данных типа нестандартного класса макета (или массива таких типов) или ссылки,
  • не имеет виртуальных функций (10.3) и виртуальных базовых классов (10.1),
  • имеет одинаковый контроль доступа (пункт 11) для всех нестатических элементов данных,
  • не имеет базовых классов нестандартной компоновки,
  • либо не имеет нестатических членов данных в самом производном классе и не более одного базового класса с
    нестатические члены данных, или не имеет базовых классов с нестатическими членами данных, и
  • не имеет базовых классов того же типа, что и первый нестатический член данных.

(C ++ 14, [класс] №7)

Если класс является стандартным макетом, его макет хорошо определен (и два стандартных класса макета, которые имеют совместимую с макетом начальную последовательность, могут читать элементы, совместимые с макетом друг друга, через union).

Однако здесь это не так, так как у вас разные спецификаторы доступа по всему классу. В частности, прямо указано, что

Порядок распределения нестатических элементов данных с различным контролем доступа не определен

(C ++ 14, [class.mem] ¶13)


Что, как говорится, Я никогда не работал с каким-либо реальным компилятором, который когда-либо использовал эту гибкость, предлагаемую стандартом — каждый известный мне компилятор использует спецификаторы доступа для проверок во время компиляции, но полностью игнорирует их в том, что касается компоновки членов.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]