Подтвердить что ты не робот

Как доступ для частных переменных, реализованных на С++ под капотом?

Как компилятор контролирует защиту переменных в памяти? Есть ли бит тега, связанный с частными переменными внутри памяти? Как это работает?

4b9b3361

Ответ 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 сильно отличаются от других участников после компиляции.

Там есть, однако важный аспект заключается в том, что члены данных не должны выкладываться в памяти в том порядке, в котором они отображаются в определении класса, но они требуются для переменных с тем же уровнем доступа.