Помимо обычного объяснения того, что они видны или нет для производных классов, есть ли у них какая-либо другая разница?
Если вы сделаете его более заметным, он займет больше или меньше памяти, замедлит работу или...?
Помимо обычного объяснения того, что они видны или нет для производных классов, есть ли у них какая-либо другая разница?
Если вы сделаете его более заметным, он займет больше или меньше памяти, замедлит работу или...?
Помимо доступности членов извне или для производных классов, спецификаторы доступа могут влиять на макет объекта.
Цитата из моего другого ответа:
Обычно адрес памяти для элементов данных увеличивается в порядке их определения в классе. Но этот порядок может быть нарушен в любом месте, где встречаются спецификаторы доступа (private
, protected
, public
). Это подробно обсуждалось в Внутри объектной модели C++ автор Lippman.
Выдержка из журнала пользователей C/C++,
Однако компилятору не разрешено выполнять эту перестановку самостоятельно. Стандарт требует, чтобы все данные, находящиеся в одном общедоступном:, защищенном: или частном:, были размещены компилятором в указанном порядке. Однако, если вы перемежаете свои данные спецификаторами доступа, компилятору разрешается переупорядочивать блоки данных, разделенные спецификаторами доступа, для улучшения макета, вот почему некоторым людям нравится помещать доступ перед каждым элементом данных.
Интересно, не так ли?
Из n3225
, 9.2 [class.mem] примечание 15
Нестатические элементы данных класса (не объединенного) с одинаковым контролем доступа (раздел 11) распределяются таким образом, чтобы более поздние члены имели более высокие адреса в объекте класса. Порядок размещения нестатических элементов данных с различным контролем доступа не определен (11).
Это означает, что с учетом следующего объявления:
class Foo {
public: int a;
private: int b;
public: int c;
private: int d;
};
Только следующие утверждения применяются стандартом:
Foo foo;
assert(&foo.a < &foo.c);
assert(&foo.b < &foo.d);
Цитата @Nawaz может быть истолкована как предоставление 4 блоков, которые можно свободно смешивать, но это не так. Объявление Foo
полностью эквивалентно:
class Foo' {
public: int a,c;
private: int b,d;
};
Действительно, компилятор полностью игнорирует (для этой цели), появлялся ли спецификатор один раз или несколько раз, и указание его каждый раз является ложным и в лучшем случае замедляет компиляцию из-за дополнительного синтаксического анализа. Для читателя-человека это может быть понятнее... но это очень субъективно.