Objektumok memóriakezelése

Dobra Gábor · 2019.02.27.

A mai óra célja az érték szerint kezelhető objektumok, és azok memóriakezelésének megismerése.

Felkészülés a gyakorlatra

1. Mitírki

Tegyük fel, hogy a kommenttel ellátott sorok a kommentben szereplő számot írják ki a képernyőre. Mit írnak ki a main-ben szereplő kifejezések? (Forrás: infocpp)

class String
{
    char *p;
    unsigned int len;
public:
    String();                               // 1
    String(const char*);                    // 2
    String(const String&);                  // 3
    String& operator=(String const&);       // 4
    ~String();                              // 5

    String operator+(String const&) const;  // 6
    char& operator[](int);                  // 7
    const char& operator[](int) const;      // 8
    const char* c_str() const;              // 9
};

String f1()
{
    String s("hello");
    return s;
}

void f2(String s)
{
    std::cout << s.c_str() << std::endl;
}

int main()
{
    String s1("mitírki");
    String s2;
    String s3 = s2;
    String s();

    char c = s3[3];
    s2 = s3;
    s2 = s3 + s1;

    String s4 = f1();
    f2(s4);
    f2("hello");
}
Megoldás
int main()
{
    String s1("mitírki");   // 2
    String s2;              // 1
    String s3 = s2;         // 3
    String s(); // most vexing parse, függvénydeklaráció!

    char c = s1[3];         // 7
    s1[5] = c+1;            // 7
    s2 = s3;                // 4
    s2 = s3 + s1;           // 6 1? 3 5 4 5

    String s4 = f1();       // 2 [3 5] [3 5]
    f2(s4);                 // 3 9 5
    f2("hello");            // 2 9 5

    // 5 5 5 5
}

Jelmagyarázat:

  • 1?: az operator+ belül valamilyen konstruktort használ, hogy létrehozza az objektumot, amit visszaad, de nem tudjuk, hogy melyiket.
  • [3 5]: a fordítónak megengedi a szabvány, hogy ott egy vagy két másolatot kioptimalizáljon, Return Value Optimization (RVO) a jelenség neve.

2. std::string és std::vector

A gyakorlatvezető segítségével ismerkedjetek meg az std::string és az std::vector alapvető használatával!

Összefoglaló

std::string

  • dinamikus sztring típus, #include <string>
  • hasonló az előadáson / jegyzetben látotthoz
  • méret lekérdezése: str.size() vagy str.length()
  • indexelés: str[i], nem ellenőriz túlindexelést!
  • összefűzés: van operator+ és operator+=

std::vector

  • dinamikus tömb típus, #include <vector>
  • vektor: szám-N-es, vagy nem is feltétlen számokból, hanem bármilyen típusból
  • kacsacsőrök közt kell megadni, hogy milyen típusú elemeket akarunk benne tárolni: std::vector<int> vagy akár std::vector<std::string>
  • méret lekérdezése: vec.size()
  • indexelés: vec[i], nem ellenőriz túlindexelést!
  • végére fűzés: vec.push_back(elem), megnyújtja a tömböt

3. Sztringmegfordítás

Aki O(n²) fordít meg egy stringet, annak nem is árt egy kis tréning. :)

Forrás

Írj függvényt, ami megfordít egy std::string-et! Adjatok minél többféle megoldást!

4. További feladatok

Oldjuk meg az alábbi feladatokat!

Nyugodtan kérdezzetek a gyakorlatvezetőtől, hogy "van-e olyan művelete a sztringnek / vektornak, hogy..." mert valószínűleg van, és szabad is használni.

  • Írj függvényt, ami visszaadja egy sztring madárnyelvesített másolatát!
  • Írj függvényt, ami visszaadja a számot római számként!
  • Írj függvényt, ami visszaadja egy szám prímtényezőit!
  • Írj függvényt, ami visszaadja egy tömb csak páros elemeit!
  • Írj függvényt, ami visszaadja a 3-jegyű tükörszámokat (aba-alakúakat)!
  • Írj függvényt, ami visszaadja egy másodfokú egyenlet megoldásait (0, 1, 2 db).
  • Írj függvényt, ami egy sztringet elválaszt valamilyen karakter mentén (boost::split)! Pl. szetvalaszt("a,b,c", ',') -> {"a", "b", "c"}
Megoldás