Dowiedziałem się, że nigdy nie mogę uzyskać dostępu do zmiennej prywatnej, tylko z funkcją get w klasie. Ale w takim razie dlaczego mogę uzyskać do niego dostęp w konstruktorze kopiującym?
Przykład:
Field::Field(const Field& f)
{
pFirst = new T[f.capacity()];
pLast = pFirst + (f.pLast - f.pFirst);
pEnd = pFirst + (f.pEnd - f.pFirst);
std::copy(f.pFirst, f.pLast, pFirst);
}
Moja deklaracja:
private:
T *pFirst,*pLast,*pEnd;
c++
private
access-specifier
Król demonów
źródło
źródło
const&
lub pobierający według wartości dla każdego? Wtedy są one tylko „prywatne do zapisu”, & ponieważ wartości marnują zasoby i zawodzą dla członków, których nie można skopiować.) Jestem zdumiony takim sukcesem tak pustego pytania, pytającego o tworzenie kopii, całkowicie ignorując jego znaczenie, i żadna odpowiedź nie używa podstawowej logiki do obalenia tego. Wyjaśniają suche szczegóły techniczne, ale jest znacznie prostsza odpowiedź na pytanie, które migałoOdpowiedzi:
IMHO, istniejące odpowiedzi słabo wyjaśniają „dlaczego” tego - koncentrując się zbytnio na powtarzaniu, jakie zachowanie jest prawidłowe. „modyfikatory dostępu działają na poziomie klasy, a nie obiektu”. - tak ale dlaczego?
Nadrzędną koncepcją jest tutaj to, że to programista (programiści) projektujący, piszący i utrzymujący klasę powinien (powinni) rozumieć enkapsulację obiektową pożądaną i uprawnioną do koordynowania jej implementacji. Tak więc, pisząc
class X
, kodujesz nie tylko to, jak pojedynczyX x
obiekt może być używany przez kod z dostępem do niego, ale także:X
obiekty współpracują w celu zapewnienia zamierzonych zachowań, jednocześnie przestrzegając warunków końcowych i niezmienników z projektu.To nie tylko konstruktor kopiujący - bardzo wiele operacji może obejmować dwie lub więcej instancji Twojej klasy: jeśli porównujesz, dodajesz / mnożesz / dzielisz, kopiujesz konstruowanie, klonowanie, przypisywanie itp., To często jest tak, że albo po prostu musi mieć dostęp do prywatnych i / lub chronionych danych w innym obiekcie, albo chce, aby umożliwiał prostszą, szybszą lub ogólnie lepszą implementację funkcji.
W szczególności te operacje mogą chcieć skorzystać z uprzywilejowanego dostępu, aby wykonać następujące czynności:
shared_ptr
s do danych referencyjnych itp.auto_ptr<>
„przenosi” własność na obiekt w budowieunordered_map
członka, ale publicznie tylko ujawniająbegin()
iend()
iteratory - z bezpośrednim dostępem dosize()
ciebie możnareserve
by przyspieszyć kopiowanie; Co gorsza, jeśli tylko oni wystawiaćat()
iinsert()
a inaczejthrow
....źródło
this == other
każdym razem, gdy uzyskujesz dostępother.x
, byłoby ogromnym narzutem w czasie wykonywania, gdyby modyfikatory dostępu działały na poziomie obiektu.this == other
każdym razem, gdy uzyskujesz dostępother.x
" - pomija sedno - gdybyother.x
było akceptowane tylko w czasie wykonywania, gdy jest równoważnethis.x
, nie byłobyother.x
po pierwsze dużo pisania wskaźników ; kompilator może równie dobrze zmusić cię do napisaniaif (this == other) ...this.x...
tego, co zamierzałeś zrobić. Twoja koncepcja „wygody (nawet bardziej, jeśli zmienne prywatne byłyby publiczne)” również mija się z celem - sposób zdefiniowania Standardu jest wystarczająco restrykcyjny, aby umożliwić właściwe hermetyzację, ale nie jest niepotrzebnie niewygodny.Modyfikatory dostępu działają na poziomie klasy , a nie obiektu .
Oznacza to, że dwa obiekty tej samej klasy mogą wzajemnie uzyskiwać dostęp do prywatnych danych.
Czemu:
Przede wszystkim ze względu na wydajność. Sprawdzanie, czy za
this == other
każdym razem, gdy uzyskujesz dostępother.x
, wymagałoby sprawdzenia, czy modyfikatory dostępu działały na poziomie obiektu, byłoby nie do pominięcia kosztem czasu wykonania .Jest to również trochę logiczne semantycznie, jeśli myślisz o tym w kategoriach zakresu: „Jak dużą część kodu muszę pamiętać, modyfikując zmienną prywatną?” - Musisz pamiętać o kodzie całej klasy, a to jest ortogonalne, do których obiekty istnieją w czasie wykonywania.
Jest to niezwykle wygodne podczas pisania konstruktorów kopiujących i operatorów przypisania.
źródło
Możesz uzyskać dostęp do prywatnych członków klasy z poziomu klasy, nawet z innej instancji.
źródło
Aby zrozumieć odpowiedź, chciałbym przypomnieć kilka pojęć.
this
wskaźnik jest przekazywany do każdej funkcji, gdy jest wywoływana.Teraz to z powodu
this
wskaźnikowi funkcja jest w stanie zlokalizować zmienne tej konkretnej instancji. bez względu na to, czy jest prywatny czy publiczny. można uzyskać do niego dostęp wewnątrz tej funkcji. Teraz, jeśli przekażemy wskaźnik do innego obiektu tej samej klasy. używając tego drugiego wskaźnika będziemy mogli uzyskać dostęp do prywatnych członków.Mam nadzieję, że to odpowiada na twoje pytanie.
źródło
Konstruktor kopiujący jest funkcją składową klasy i jako taki ma dostęp do elementów składowych danych klasy, nawet tych zadeklarowanych jako „prywatne”.
źródło