спецификаторы доступа к членам класса и двоичный код - PullRequest
3 голосов
/ 03 мая 2010

Я понимаю, что типичные спецификаторы доступа, и что они значат. «публичные» участники доступны везде, «частные» участники доступны только одному классу и друзьям и т. д.

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

Другой способ выразить это - если бы это был идеальный мир, в котором программисты всегда делали правильный выбор (например, не обращались к членам, которые могут измениться позже, и использовали только четко определенные члены, которые должны оставаться неизменными между реализациями), были бы они причиной использовать эти вещи?

Ответы [ 5 ]

8 голосов
/ 03 мая 2010

Спецификаторы доступа существуют только для целей компиляции. Любая память в пределах выделения вашей программы может быть доступна любой части исполняемого файла; нет общедоступной / частной концепции во время выполнения

1 голос
/ 03 мая 2010

Майкл ответ правильный. Спецификаторы доступа не влияют напрямую на полученный код.

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

class A {
private:
    int x;
};

class B {
protected:
    int x;
};

class C : public A, public B {
public:
    int &get_x() { return x; } // only B::x is accessible, no error.
};

Так что они определенно служат более высокой цели, чем ограничение программиста.

0 голосов
/ 03 мая 2010

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

При этом было бы возможно установить компилятор так, чтобы он модифицировал код всякий раз, когда вызывается функция-член класса private, чтобы определить, когда функция вызывается ненадлежащим образом (добавьте дополнительный параметр и установите его в некоторое ожидаемое значение, когда функция вызывается из класса; вызов функции из-за пределов класса может привести к неверному значению). Проблема с этим подходом заключается в том, что вы делаете сейчас? Запереться? Ничего не делать и вернуть неверные данные? Эти типы проблем (относительно) легко обнаруживаются и могут быть исправлены во время компиляции, поэтому редко можно встретить такие вещи во время выполнения (вне средств отладки или профилирования кода).

0 голосов
/ 03 мая 2010

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

Нет воздействия во время выполнения. Вы можете написать программу с правильными модификаторами доступа, скомпилировать ее с c++ -Dprotected=public -Dprivate=public file.cc, и она должна создавать и генерировать почти точно такой же код (есть некоторые гипотетические предостережения, такие как расположение данных классов).

0 голосов
/ 03 мая 2010

Ответ на ваш вопрос может отличаться в зависимости от компилятора, но в целом не будет никакой разницы. Можно представить себе среду, для которой скомпилированный код может иметь разные характеристики для этих разных возможностей доступа, но я не знаю ни одной из существующих.

...