Ce face const
O variabilă const primește o valoare la declarare și nu mai poate fi schimbată. Este o promisiune verificată de compilator: dacă încerci x = 6;, primești eroare de compilare. Folosește const peste tot unde valoarea nu trebuie să se schimbe; codul devine mai ușor de înțeles.
Cea mai frecventă folosire este parametrul const T&: funcția primește obiectul fără copie (rapid), dar nu îl poate modifica. Pentru o metodă de clasă, const pus după paranteze înseamnă că metoda nu modifică obiectul și poate fi apelată pe obiecte const.
La pointeri contează poziția: const int* p înseamnă „nu poți modifica valoarea prin p” (dar p poate arăta în altă parte), iar int* const p înseamnă „p arată mereu în același loc” (dar valoarea se poate modifica). Regula: const se aplică la ce are imediat în stânga (sau în dreapta, dacă e primul).
Exemple
Exemplul 1: Constante și parametri const
const std::string& evită copierea textului; funcția îl poate citi, dar nu îl poate modifica.
#include <print>
#include <string>
const double TVA = 0.21;
void afiseaza_factura(const std::string& client, double suma) {
std::println("Client: {}", client);
std::println("Total cu TVA: {:.2f} lei", suma * (1 + TVA));
}
int main() {
const int luni = 12;
afiseaza_factura("Ana Popescu", 1000);
std::println("Abonament anual: {} lei", 50 * luni);
}
Rezultat
Client: Ana Popescu
Total cu TVA: 1210.00 lei
Abonament anual: 600 lei
Exemplul 2: Metode const
Pe un obiect const se pot apela doar metodele marcate const. Fără const la sold(), apelul din afiseaza nu s-ar compila.
#include <print>
class Cont {
public:
void depune(double suma) { sold_ += suma; }
double sold() const { return sold_; }
private:
double sold_ = 0;
};
void afiseaza(const Cont& c) {
std::println("Sold: {} lei", c.sold());
}
int main() {
Cont c;
c.depune(250);
afiseaza(c);
}
Rezultat
Sold: 250 lei
Exemplul 3: Pointer la const și pointer constant
#include <print>
int main() {
int a = 1, b = 2;
const int* p = &a; // nu pot modifica *p
p = &b; // dar pot muta p
std::println("*p = {}", *p);
int* const q = &a; // nu pot muta q
*q = 10; // dar pot modifica valoarea
std::println("a = {}", a);
}
Rezultat
*p = 2
a = 10
Greșeli frecvente
- Transmiți obiecte mari prin valoare (
void f(std::vector<int> v)) când doar le citești. Se face o copie la fiecare apel; foloseșteconst std::vector<int>& v. - Uiți
constla metodele care doar citesc. Apoi nu le poți apela pe obiecte primite caconst&și primești erori greu de înțeles la prima vedere. - Confunzi
constcuconstexpr. Unconstpoate primi o valoare calculată la rulare (de exemplu citită de la tastatură);constexprcere o valoare cunoscută la compilare.
Comenzi înrudite
constexpr: Cere ca o valoare să fie calculată la compilare; o funcție constexpr poate rula atât la compilare, cât și la rulare.mutable: Permite modificarea unui membru chiar și în metode const sau modificarea variabilelor capturate prin copie într-o lambda.referințe (&, &&): O referință este un alt nume pentru o variabilă existentă; tot ce faci cu referința se face de fapt cu variabila originală.static_cast, dynamic_cast, const_cast, reinterpret_cast: Cele patru conversii explicite: static_cast (obișnuite), dynamic_cast (clase), const_cast (const) și reinterpret_cast (biți).std::string_view: Vedere doar pentru citire asupra unui text existent, fără copiere; se poate micșora la capete.