Nel tuo esempio è probabilmente una pessima idea modificare _a[i]
.
Avendo detto che mi piacerebbe approfondire un po 'di più:
const
è una parola chiave molto utile. Se leggi alcuni libri di Bjarne o di Scott, c'è scritto di usare const il più spesso possibile. Inoltre la modifica dei dati in funzione dichiarata const
non è solo possibile, a volte è una buona pratica! Basta ricordare che è necessario prestare attenzione quando si decide se il tuo caso è uno di quei "un po 'di volte. Perché mai sulla Terra metterebbero la parola chiave mutable
in C ++ se non dovrebbe essere usato?
Un esempio (da uno dei suddetti autori se ricordo bene) di buon utilizzo di mutable
:
Considera poligono di classe:
class Polygon
{
void calculate_area() { /* we calculate m_area */ }
std::vector<Vertex> m_vertexes;
double m_area;
public:
Polygon(std::initializer_list<Vertex> v_list): m_vertexes(v_list) {}
double area() const { return m_area; }
void add_vertex(Vertex v)
{
m_vertexes.push_back(v);
calculate_area();
}
};
È abbastanza diretto, non è vero? Non vogliamo calcolare l'area ogni volta che viene richiesto di restituirlo, quindi memorizziamo il suo valore in m_area
variabile membro e restituiamo questa variabile. Il metodo double area()
è const
, dopotutto non cambia nulla. Il fatto è che dobbiamo calcolare l'area ogni volta che cambiamo il nostro poligono! Diciamo che aggiungiamo cento vertici uno per uno ... Cento ricalcoli di area! 99 di quelli totalmente inutili. Vogliamo ricalcolare solo se ci viene richiesto di consegnare l'area. Quindi cosa facciamo?
Usiamo mutable
!
class Polygon
{
void calculate_area() const
{
/* we calculate m_area */
m_recalculate_area = false;
}
std::vector<Vertex> m_vertexes;
mutable bool m_recalculate_area = false;
mutable double m_area = 0.0;
public:
Polygon(std::initializer_list<Vertex> v_list): m_vertexes(v_list)
{ m_recalculate_area = true; }
double area() const
{
if(m_recalculate_area)
{ calculate_area(); }
return m_area;
}
void add_vertex(Vertex v)
{
m_vertexes.push_back(v);
m_recalculate_area = true;
}
};
L'effetto è molto carino: per un utente del nostro metodo di classe double area()
continua a non modificare l'oggetto su cui sta lavorando, quindi è ancora const
. Ma dentro abbiamo guadagnato molto! L'area verrà ricalcolata solo quando ce n'è bisogno. Se nessuno chiede un'area, non verrà calcolato affatto!
Quindi, a quanto ho capito, const
dovrebbe indicare che "per quanto riguarda l'utente della classe" il metodo non modifica l'oggetto. L'utente della nostra API di solito non è interessato ai dettagli di implementazione. Se lo è, allora abbiamo la documentazione :).
Ma attenzione: usando mutable
perché "sono poche righe di codice in meno" o qualcosa del genere è un grosso errore. Se rendi il tuo metodo const
, mantieni la tua parola e usa mutable
con la massima cura! Altrimenti, voi e gli utenti del vostro codice presto saranno in grossi problemi.