Sono nuovo di C ++, proveniente da Java.
In Java, tutte le variabili (eccetto primitive) sono essenzialmente dei puntatori. Tengono l'indirizzo di qualunque cosa stiano "trattenendo".
Quindi qualsiasi struttura dati Java memorizza i dati per riferimento. Puoi anche archiviare in base al valore, ad esempio salvare e restituire una copia di qualsiasi elemento archiviato, ma ciò richiederebbe un lavoro supplementare e non è nativo per la lingua.
Ad esempio, le collezioni ArrayList
, HashSet
e un semplice array archiviano tutti gli indirizzi degli elementi che "memorizzano" e non gli articoli effettivi.
Tuttavia, in C ++, hai una scelta: quando si implementa una classe contenitore, è possibile memorizzare e restituire gli articoli utente per valore o per riferimento.
Ad esempio, ecco una semplice classe Stack
che ho scritto (omessa roba irrilevante):
template <typename T> class Stack {
public:
Stack(...) : ... { }
void push(const T& item) {
if(size == capacity - 1)
enlargeArray();
data[indexToInsert++] = &item;
size++;
}
const T& pop() {
const T& item = *data[indexToInsert - 1];
data[indexToInsert - 1] = 0;
indexToInsert--;
size--;
return item;
}
int getSize() const {
return size;
}
private:
const T** data;
int indexToInsert;
int size;
int capacity;
void enlargeArray() {
// omitted
}
};
Questa struttura dati prende e restituisce i dati per riferimento. push
prende un riferimento const e pop
restituisce un riferimento const. L'array di supporto è un array di puntatori, non di oggetti.
Tuttavia push
potrebbe anche avere il seguente aspetto:
void push(T item) {
if(size == capacity - 1)
enlargeArray();
data[indexToInsert++] = item;
size++;
}
E pop
potrebbe restituire un T
, non un const T&
, ecc.
La mia domanda è: qual è l'approccio preferito in C ++? C'è c'è un approccio preferito? Quale approccio dovrei assumere normalmente quando si implementano le classi "container"?