3. Sztring osztály
Czirkos Zoltán · 2019.02.27.
Sztring osztály, dinamikus tömbre mutató adattag
#include <iostream>
#include <cstring>
class Sztring {
private:
size_t hossz; // lezáró nulla nélkül
char* adat; // lezáró nullával együtt
public:
Sztring(char const *szoveg = "") {
hossz = strlen(szoveg);
adat = new char[hossz+1];
strcpy(adat, szoveg);
}
// Kell destruktor, mert a sztringhez
// dinamikusan foglalt memóriaterület tartozik.
~Sztring() {
delete[] adat;
}
// Ha minden sztringnek saját dinamikusan foglalt
// memóriaterülete van, akkor azoknak is, amelyeket
// egy másik sztring alapján inicializálunk:
// Sztring s1 = "alma";
// Sztring s2 = s1; <- az ilyennek
// Általánosságban: ha van destruktor, akkor kell copy ctor.
Sztring(Sztring const & orig) {
hossz = orig.hossz;
adat = new char[hossz+1];
strcpy(adat, orig.adat);
}
// Ha két sztring közötti értékadást csinálunk, akkor
// annak nem szabad az adattagok közti értékadásnak lennie,
// mert akkor a pointer is másolódik (és lenne egy memleak
// meg közös tömb). Ezért saját operator= kell, ami
// pl. ilyenkor hívódik:
// Sztring s1 = "alma", s2 = "korte";
// s2 = s1; <- ilyenkor
// Érdemes ezt összehasonlítani a fenti sorral! Nem
// Sztring s2 = s1;
// hanem
// s2 = s1;
// A Sztring-gel kezdődő sor konstruktor, az anélküli pedig
// értékadó operátor.
// Általában: ha kellett dtor, akkor kelleni fog op= is.
// Egyébként op= összerakható a dtor-ból és a copy ctor-ból.
Sztring & operator=(Sztring const & orig) {
if (this != &orig) {
delete[] adat;
hossz = orig.hossz;
adat = new char[hossz+1];
strcpy(adat, orig.adat);
}
return *this;
}
size_t size() const {
return hossz;
}
char const & operator[] (size_t idx) const {
return adat[idx];
}
char & operator[] (size_t idx) {
return adat[idx];
}
// Sztringek összefűzése. Semmi különös, csak dinamikus és
// figyelni kell a méretre. Egy fontos dolog, hogy a
// Sztring uj;
// sorban, alapértelmezett konstruktorral létrehozott Sztring
// karaktertömbjét törölni kell (következő sorban), különben
// memóriaszivárgás lenne.
// A lokális változó (uj) visszatéréskor megszűnik, előtte
// viszont az érték típusú visszatérési érték miatt lemásolódik
// a másoló konstruktorral. Ezt a másolást általában a fordítók
// ki szokták optimalizálni, így nem kell attól tartanunk, hogy
// ez lassú lenne.
Sztring operator+(Sztring const & rhs) const {
Sztring uj;
delete[] uj.adat;
uj.hossz = this->hossz + rhs.hossz;
uj.adat = new char[uj.hossz + 1];
strcpy(uj.adat, this->adat);
strcat(uj.adat, rhs.adat);
return uj;
}
};
std::ostream & operator<<(std::ostream & os, const Sztring & s) {
for (size_t i = 0; i != s.size(); ++i)
os << s[i];
return os;
}
int main() {
Sztring a = "alma";
Sztring b = "fa";
Sztring c = "x";
c = a+b; // c.operator=( a.operator+(b) )
std::cout << c;
return 0; // c, b, a dtor
}