modifica: Leggendo la FAQ un po 'più a lungo mi piace l'idea che l'operatore << >> sovraccarichi e aggiunga come amico di quelle classi, tuttavia non sono sicuro di come ciò non rompa l'incapsulamento
Come spezzerebbe l'incapsulamento?
Si interrompe l'incapsulamento quando si consente l' accesso senza restrizioni a un membro di dati. Considera le seguenti classi:
class c1 {
public:
int x;
};
class c2 {
public:
int foo();
private:
int x;
};
class c3 {
friend int foo();
private:
int x;
};
c1
è ovviamente non incapsulato. Chiunque può leggere e modificare x
al suo interno. Non abbiamo modo di applicare alcun tipo di controllo di accesso.
c2
è ovviamente incapsulato. Non c'è accesso pubblico a x
. Tutto quello che puoi fare è chiamare la foo
funzione, che esegue alcune operazioni significative sulla classe .
c3
? È meno incapsulato? Permette l'accesso illimitato ax
? Permette l'accesso a funzioni sconosciute?
No. Permette precisamente a una funzione di accedere ai membri privati della classe. Proprio come ha c2
fatto. E proprio come c2
, l'unica funzione che ha accesso non è "una funzione casuale, sconosciuta", ma "la funzione elencata nella definizione della classe". Proprio come c2
, possiamo vedere, semplicemente guardando le definizioni delle classi, un elenco completo di chi ha accesso.
Quindi, come è esattamente questo meno incapsulato? La stessa quantità di codice ha accesso ai membri privati della classe. E tutti coloro che hanno accesso sono elencati nella definizione della classe.
friend
non rompe l'incapsulamento. Ciò rende alcuni programmatori di persone Java a disagio, perché quando dicono "OOP", in realtà significano "Java". Quando dicono "Incapsulamento", non significano "i membri privati devono essere protetti da accessi arbitrari", ma "una classe Java in cui le uniche funzioni in grado di accedere ai membri privati, sono membri della classe", anche se questa è una totale assurdità per diverse ragioni .
Innanzitutto, come già mostrato, è troppo restrittivo. Non c'è motivo per cui i metodi degli amici non dovrebbero fare lo stesso.
Secondo, non è abbastanza restrittivo . Considera una quarta classe:
class c4 {
public:
int getx();
void setx(int x);
private:
int x;
};
Questo, secondo la suddetta mentalità Java, è perfettamente incapsulato.
Eppure, consente a chiunque di leggere e modificare assolutamente x . Che senso ha questo senso? (suggerimento: non lo fa)
In conclusione: l'incapsulamento riguarda la capacità di controllare quali funzioni possono accedere ai membri privati. E ' non è su esattamente dove si trovano le definizioni di queste funzioni.