C++ könyvtárak

Kitlei Róbert

2008/2009 tavaszi félév

Megjegyzés

A továbbiakban tárgyalt deklarációk mindegyike az std névtérben található, a fóliákon úgy szerepelnek, mintha érvényben lenne az using namespace std direktíva.

Sztringek

C sztringeknél (0-val lezárt char* tömb) helyett gyakran string típussal ábrázoljuk a szövegeket C++ nyelven.

Előnyök

Hátrány: nagyobb tárigény

Sztringek

string s;
for (char c ='a'; c <= 'z'; ++c) s += c;
// "abc..."

string s2 = s + "0123456789";

Sztringek

string s;
s += 65; // karakter hozzáfűzése
// eredmény: "a"

Párok

Pár: két, valamilyen szempontból összetartozó értéket fog össze

pair<char, string> p('a', "bcd");
cout << p.first;
cout << p.second;
// kimenet: "abcd"

Folyamok

ifstream ifs("a.txt");

Folyamok

// gyakori beolvasási séma
while (cin >> adat) {
...
}

STL

STL (Standard Template Library): a nyelv részévé vált könyvtár

STL

Az STL fő céljai

STL

Sorozat jellegű tárolók

// az STL osztályokat általában
// a megegyező nevű fejléc tartalmazza
#include <vector>

vector<int> v(10); // 10 elemű vektor
for (int i = 0; i < 10; ++i) v[i] = i;

STL

Sorozat jellegű tárolók

vector<int> v(3);   // elemek: v[0], v[1], v[2]
int i = v[3]; // nincs hiba, i értéke ismeretlen
int j = v.at(3); // out_of_range kivétel

STL

Sorozat jellegű tárolók

#include <list>

list<int> l;
for (int i = 9; i >= 0; --i) l.push_front(i);
// l ≡ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// a push_front a tároló elejére helyezi az elemet
// a push_back a tároló végére helyezi az elemet

STL

Asszociatív tárolók: az elemek nincsenek sorba rendezve

set<int> s;   multiset<int> m;
s.insert(1); m.insert(1); // egy elem beszúrása
s.insert(2); m.insert(2);
s.insert(2); m.insert(2);
// x 1 2 3
// s.count(x) 1 1 0
// m.count(x) 1 2 0
s.erase(2); m.erase(2);
// s.count(x) 1 0 0
// m.count(x) 1 0 0

STL

Asszociatív tárolók

STL

map<string, int> m;
m["abc"] = 1;
m["def"] = 2;

if (m["xyz"] == 0) { ... }
// nem jó, létrejön az "xyz" kulcsú elem,
// pont 0 értékkel

if (m.find("xyz") != m.end() && m["xyz"] == 0) { ... }
// ez megvizsgálja azt is, létezik-e a kulcs
// kihasználtuk, hogy && rövidzáras

STL

Bejáró (iterátor): a tároló egy elemére mutat, egy mutatóhoz nagyon hasonlóan

STL

Bejáró

// minden kulcshoz tartozó érték megnövelése eggyel
for (map<string, int>::iterator it = m.begin();
it != m.end(); ++it) {
++(it->second);
}

STL

Algoritmusok

STL

Algoritmusok leírásai

STL

Függvényobjektum vagy funktor: állapottal rendelkező függvény

// itt még nincsen szükség függvényobjektumra
void kiiro(pair<string, int> p) {
cout << p.first << " " << p.second << endl;
}

// minden elemre meghívjuk a kiiro függvényt
for_each(m.begin(), m.end(), kiiro);

STL

Függvényobjektum

struct kiiro
{
kiiro(ostream& o) : os(o) {}
void operator()(pair<string, int> p) {
os << p.first << " " << p.second << endl;
}

private:
ostream& os;
};

for_each(m.begin(), m.end(), kiiro(cout));

STL

Függvényobjektum

find_if(l.begin(), l.end(), bind1st(less<int>(), 3));
// bind1st: a függvény második argumentumát rögzíti
// (? < ?) ===> (3 < ?)
// az első, háromnál nagyobb elem bejáróját adja vissza
// ha nincs ilyen elem, l.end() az eredmény

count_if(v.begin(), v.end(), bind2st(less<int>(), 6));
// a vektor hatnál kisebb elemeinek száma
// feltétel: (? < 6)

STL

Előre definiált függvényobjektumok

vector<int>::iterator vit =
remove(v2.begin(), v2.end(), 1);
// ha v2 kezdetben [1 1 2 1 3] ===> [2 3|2 1 3]
// a függőleges vonal jelzi a visszaadott bejárót,
// de v2 teljes hossza még mindig öt
vi.erase(vit, vi.end());
// eltünteti a felesleges elemeket

STL

Előre definiált függvényobjektumok

list<int> l;
copy(istream_iterator<int>(cin),
istream_iterator<int>(),
back_inserter(l)); // lista beolvasása
copy(l.begin(), l.end(), ostream_iterator<int>(cout));
// lista kiírása
copy(l.rbegin(), l.rend(), ostream_iterator<int>(cout));
// lista kiírása fordított sorrendben