Za kulisami publicznego, prywatnego i chronionego
Staram się zanurkować głębiej i zrozumieć różnice między Public | Prywatne | Chronione z perspektywy niskiego poziomu, w C ++.
W jaki sposób różnice między trzema wyrażają się w pamięci?
Odpowiedzi
private
, public
I protected
nie powoduje członkowie mają być przechowywane w określonych regionach pamięci. Dostęp jest sprawdzany przez kompilator. Na najniższym poziomie nie ma różnicy.
Jednak specyfikatory dostępu mają wpływ na to, co gwarantuje, że uzyskasz kolejność, w jakiej elementy członkowskie klasy są rozmieszczone w pamięci.
Ze standardowej wersji roboczej C ++ 17 :
Niestatyczne składowe danych klasy (nie-unii) z tą samą kontrolą dostępu (klauzula [class.access]) są przydzielane, aby późniejsi członkowie mieli wyższe adresy w obiekcie klasy. Kolejność przydzielania niestatycznych składowych danych z różną kontrolą dostępu jest nieokreślona (klauzula [klasa.access]). Wymagania dotyczące dostosowania implementacji mogą spowodować, że dwóch sąsiednich członków nie zostanie przydzielonych bezpośrednio po sobie; tak może być wymagania dotyczące przestrzeni do zarządzania funkcjami wirtualnymi ([class.virtual]) i wirtualnymi klasami bazowymi ([class.mi]).
Oznacza to, że dla
struct foo {
private:
int x;
protected:
int a;
int b;
public:
int m;
int n;
private:
int y;
};
Masz tylko gwarancję, że pamięć x
jest wcześniej y
, a
poprzedza b
i m
poprzedza n
. Poza tym kolejność, w jakiej członkowie są ułożeni w pamięci, jest nieokreślona.
Jednak rzadko kolejność członków w pamięci jest użyteczną informacją. Dlatego nie jest błędem stwierdzenie, że specyfikatory dostępu nie mają nic wspólnego z „pamięcią niskiego poziomu”.
Na najniższym poziomie (reprezentacja obiektów w bajtach) nie ma absolutnie żadnej różnicy między publicznym, prywatnym i chronionym. W większości kompilatory mogą (ale nie muszą) zmieniać kolejności członków zgodnie z ich widocznością.
Na poziomie pośrednim (zachowanie w czasie wykonywania) różnica jest niewielka, jeśli w ogóle. Jeśli możesz znaleźć publiczny wskaźnik do prywatnych danych, możesz z nich bezpiecznie korzystać. W szczególności różni się to od constness, w którym użycie wskaźnika innego niż const do zmiany danych const jest jawnie niezdefiniowanym zachowaniem i może powodować błędy SIGSEGV.
Różnica jest tylko na najwyższym poziomie. Możesz używać publicznych członków z dowolnego miejsca, podczas gdy prywatni członkowie mogą być używane tylko w klasie, w której są zadeklarowani, a chroniony element członkowski może być używany z ich klasy i wszystkich klas dziedziczących - ale przyjaźń może umożliwić określonym klasom funkcji dostęp do prywatnych lub chronionych dane.
Ani trochę.
Kompilator przyznaje / odmawia dostępu.
Każdy dostęp, który nie pasuje do odpowiedniej widoczności (kontrolowanej przez klasę obiektu, do którego uzyskiwany jest dostęp, za pomocą wskaźnika lub nie) jest blokowany przed budowaniem.
Uwaga:
Inne odpowiedzi pożytecznie omawiają wpływ widoczności na porządek w pamięci.
Jakkolwiek odpowiedziałem na inne pytanie, które przeczytałem w postach PO „W jaki sposób funkcje ochrony pamięci są wykorzystywane do implementacji dostępności / widoczności członków?”, Które dotyczące przyczyny i skutku jest pytaniem odwrotnym. Lub tylko uporządkowanie / ustrukturyzowanie elementów w różnie skonfigurowanych pamięciach jest narzędziem do osiągnięcia pożądanego efektu widoczności, co z kolei wymagałoby (ale nie powodowałoby) uporządkowania elementów w określony sposób.
Tzn. Nie widzę konfliktu między odpowiedziami, tylko inną interpretację pytania.