struct în C++

Clase și obiecte C++98 (inițializare cu nume de câmpuri: C++20)

Grupează mai multe valori într-un singur tip; ca o clasă, dar cu membri publici implicit.

Sintaxă
struct Nume {
    Tip membru1;
    Tip membru2 = valoare_implicita;
};
Nume x{v1, v2};
Nume y{.membru1 = v1};   // C++20

Ce face struct

O struct pune la un loc date care țin împreună: numele și nota unui elev, coordonatele unui punct, datele unui produs. Membrii sunt publici implicit, deci se accesează direct cu punct: p.pret.

O structură simplă (fără constructori scriși de tine) este un agregat și se inițializează cu acolade, în ordinea membrilor: Produs p{"Lapte", 7.2};. Din C++20 poți numi câmpurile: Produs p{.nume = "Lapte", .pret = 7.2}; (în ordinea declarării). Membrii pot avea valori implicite.

În C++, struct poate avea și metode, constructori, moștenire, exact ca o class. Diferența este doar accesul implicit (public față de private), inclusiv la moștenire.

Exemple

Exemplul 1: Structură cu inițializare și vector de structuri

#include <print>
#include <string>
#include <vector>

struct Produs {
    std::string nume;
    double pret;
    int stoc = 0;
};

int main() {
    std::vector<Produs> raft = {
        {"Lapte", 7.2, 30},
        {"Pâine", 4.5, 12},
        {"Cafea", 32.5},  // stoc rămâne 0
    };
    for (const auto& p : raft) {
        std::println("{:<6} {:>6.2f} lei, stoc {}", p.nume, p.pret, p.stoc);
    }
}

Rezultat

Lapte    7.20 lei, stoc 30
Pâine    4.50 lei, stoc 12
Cafea   32.50 lei, stoc 0

Exemplul 2: Inițializare cu nume de câmpuri (C++20)

Câmpurile numite trebuie date în ordinea declarării; cele omise primesc valoarea implicită.

#include <print>
#include <string>

struct Setari {
    std::string limba = "ro";
    int marime_font = 14;
    bool mod_intunecat = false;
};

int main() {
    Setari s{.marime_font = 18, .mod_intunecat = true};
    std::println("limba={}, font={}, întunecat={}", s.limba, s.marime_font, s.mod_intunecat);
}

Rezultat

limba=ro, font=18, întunecat=true

Exemplul 3: Structură cu metode și comparație

#include <cmath>
#include <print>

struct Punct {
    double x = 0, y = 0;

    double distanta(const Punct& alt) const {
        return std::hypot(x - alt.x, y - alt.y);
    }
    bool operator==(const Punct&) const = default;
};

int main() {
    Punct a{0, 0}, b{3, 4};
    std::println("Distanța: {}", a.distanta(b));
    std::println("a == b: {}", a == b);
    std::println("b == (3,4): {}", b == Punct{3, 4});
}

Rezultat

Distanța: 5
a == b: false
b == (3,4): true

Greșeli frecvente

  • Uiți ; după acolada de închidere a structurii.
  • Adaugi un constructor într-o structură și apoi inițializarea cu acolade pe câmpuri nu mai merge cum te aștepți. Cu un constructor scris de tine, structura nu mai este agregat: acoladele apelează constructorul.
  • Compari două structuri cu == fără să definești operatorul. Nu se compilează; din C++20 adaugă bool operator==(const T&) const = default;.

Comenzi înrudite

  • class: Definește un tip nou care grupează date (membri) și funcțiile care lucrează cu ele (metode); baza programării orientate pe obiecte.
  • structured bindings (auto [a, b]): Desface o pereche, un tuplu, o structură sau un tablou în variabile separate, cu nume, într-o singură declarație.
  • union: Un tip în care toți membrii împart aceeași zonă de memorie; la un moment dat doar unul dintre ei are o valoare validă.
  • public, private, protected: Specificatorii de acces: stabilesc cine poate folosi membrii unei clase și cum se moștenește o clasă de bază.