Как компилятор контролирует защиту переменных в памяти? Есть ли бит тега, связанный с частными переменными внутри памяти? Как это работает?
Как доступ для частных переменных, реализованных на С++ под капотом?
Ответ 1
Если вы имеете в виду private
членов экземпляров, то во время выполнения нет никакой защиты. Вся защита выполняется во время компиляции, и вы всегда можете получить доступ к частным членам класса, если знаете, как они выложены в памяти. Это требует знания платформы и компилятора, а в некоторых случаях может даже зависеть от параметров компилятора, таких как уровень оптимизации.
Например, на моем Linux/x86-64 w/GCC 4.6 следующая программа печатает именно то, что вы ожидаете. Он ни в коем случае не переносится и может печатать неожиданные вещи на экзотических компиляторах, но даже эти компиляторы будут иметь свои собственные конкретные способы доступа к частным членам.
#include <iostream>
class FourChars {
private:
char a, b, c, d;
public:
FourChars(char a_, char b_, char c_, char d_)
: a(a_), b(b_), c(c_), d(d_)
{
}
};
int main()
{
FourChars fc('h', 'a', 'c', 'k');
char const *p = static_cast<char const *>(static_cast<const void *>(&fc));
std::cout << p[0] << p[1] << p[2] << p[3] << std::endl;
}
(сложный листинг есть, потому что void*
- единственный тип, к которому может быть применен любой указатель. void*
затем может быть переведен в char*
без вызова строгое правило псевдонимов. Возможно, это будет возможно и с одним reinterpret_cast
- на практике я никогда не играю в такие грязные трюки, поэтому я не слишком хорошо знаком с тем, как сделать их самым быстрым способом:)
Ответ 2
Это задача компилятора, чтобы убедиться, что некоторые члены являются закрытыми и запрещают вам использовать их. Они не any сильно отличаются от других участников после компиляции.
Там есть, однако важный аспект заключается в том, что члены данных не должны выкладываться в памяти в том порядке, в котором они отображаются в определении класса, но они требуются для переменных с тем же уровнем доступа.