L'obiettivo dell'incapsulamento è prevenire modifiche arbitrarie dei dati. Il modo più comune per ottenere questo in C ++ consiste nel mettere i dati nella sezione privata di una classe e solo mettendo un insieme limitato di metodi che possono modificare tali dati nella sezione pubblica. Ogni metodo pubblico indica all'utente cosa può essere fatto ai dati. Le implementazioni di questi metodi hanno la responsabilità di preservare lo stato valido dei dati.
Nella tua classe, operator[]
consente di modificare qualsiasi elemento dell'array. Se l'utente dovrebbe essere autorizzato a farlo, allora va bene. È una tua decisione ciò che l'utente è autorizzato a fare. Fornisci anche una protezione per assicurarti che l'indice fornito dall'utente sia entro i limiti. Questa è una buona cosa. Questo tipo di controllo è simile al metodo std::vector::at()
.
Alcuni metodi sono più difficili da giustificare:
class Foo
{
private:
int x;
public:
int& my_x() { return x; }
}
Con questa classe, l'esistenza del metodo my_x()
equivale esattamente a rendere int x
pubblico. Questo rappresenta quasi sempre l'incapsulamento rotto. Potrebbe essere necessario, a volte. Mi viene in mente il metodo std::shared_ptr::get()
, che espone il puntatore che shared_ptr
sta custodendo. A volte, tuttavia, l'utente ha legittimamente bisogno di questo tipo di accesso. Ecco perché la risposta universale a tutte le domande di ingegneria è "Dipende".
I problemi con la classe sono misure di sicurezza inadeguate nel controllo dell'indice dell'array. L'utente non viene informato quando l'indice i
è negativo. Inoltre, la stampa su cout
non è un avvertimento abbastanza strong per l'utente. Inoltre, restituire un elemento casuale dell'array quando l'indice è fuori limite è un comportamento ostile all'utente. Dico casuale perché arr[0]
non è i dati richiesti dall'utente. Lanciare un'eccezione sarebbe un'azione migliore per costringere l'utente a controllare il proprio codice per ottenere l'indice giusto.