Публичный / частный / защищенный изменяет расположение структуры в памяти? - PullRequest
0 голосов
/ 10 октября 2018

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

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

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 Ответ

0 голосов
/ 10 октября 2018

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

Класс стандартной компоновки - это класс, который:

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

(C ++ 14, [class] ¶7)

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

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

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

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


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

...