Klasa string
Używanie napisów w stylu C (tj. tablic znaków) nie jest szczególnie wygodne -
należy dbać o alokację pamięci, itd.
Biblioteka standardowa C++ udostępnia klasę string (tak naprawdę nie jest to odrębna klasa,
tylko synonim wzorca basic_string<char>), której obiekty reprezentują napisy.
Oto niektóre z metod klasy string:
- Konstruktory:
- string(); - tworzy pusty napis,
- string(const char* _Ptr, size_type _Count); - tworzy kopię napisu w stylu C o zadanej długości,
- string(const string& _Right, size_type _Roff = 0, size_type _Count = npos);
- tworzy kopię istniejącego napisu (albo jego podciągu jeśli podamy dwa ostatnie argumenty)
- append lub operator +=: dołącza znaki na końcu napisu,
- at lub operator []: zwraca znak o zadanym indeksie,
- c_str: konwertuje string na char*,
- compare: porównuje z innym napisem,
- find: wyszukuje zadany ciąg znaków,
- length: zwraca długość napisu,
- substr: zwraca podany podciąg.
Statyczne składowe klas
Jeśli zadeklarujemy pole w klasie, każdy stworzony obiekt będzie posiadał jedno takie pole.
Wyjątek stanowią pola statyczne - takie pole będzie zawsze istnieć dokładnie jedno,
niezależnie od tego ile obiektów zostało stworzonych (nawet jeśli nie istnieje żaden obiekt).
Pola statyczne definiuje się poprzedzając deklarację słowem static, np.
class A {
...
static int x;
...
};
Uwagi:
- Dostęp do pól statycznych spoza klasy wymaga użycia operatora dostępu, np. A::x w powyższym przykładzie.
- Pola statyczne inicjuje się poza definicją klasy. Można to zrobić nawet jeśli jest to pole prywatne.
Podobnie można definiować metody statyczne - są one powiązane z klasą, ale nie są powiązane z żadnym konkretnym obiektem;
w szczególności nie można w nich używać wskaźnika this. Tak samo jak w przypadku pól,
żeby się do nich odwołać spoza klasy należy użyć operatora dostępu (np. tak: Klasa::metoda()).
Klasy zagnieżdżone
Klasy można definiować wewnątrz innych klas. Robi się to w dwóch przypadkach:
- Klasa zagnieżdżona jest używana tylko przez klasę zewnętrzną (można ją zadeklarować w części
prywatnej klasy zewnętrznej)
- Klasa zagnieżdżona jest ściśle powiązana z klasą zewnętrzną, ale może być używana również poza tą
klasą. Deklarujemy ją wówczas w częsci publicznej, np.
class A {
public:
...
class B { ... };
...
};
Spoza klasy A możemy się odwoływać przez operator dostępu (np. deklarujemy obiekty przez A::B x;)
Dzięki zagnieżdżeniu klas unikamy definiowania klasy zagnieżdżonej (B w powyższym przykładzie)
w zasięgu globalnym, dzięki czemu możemy definiować wile różnych klas o tej samej nazwie.
Iteratory
Używanie kolekcji standardowych jest bardzo utrudnione (albo wręcz niemożliwe) bez
iteratorów - obiektów służących do ich przeglądania. Każda kolekcja definiuje własną
klasę iterator - jest ona zagnieżdżona, co umożliwia użycie tej samej nazwy we wszystkich
przypadkach. Dostęp do danej klasy iteratorowej uzyskuje się przy pomocy operatora dostępu, (np.
list<int>::iterator jest iteratorem listy typu int). Dostęp do elementu
wskazywanego przez iterator uzyskujemy (tak jak w przypadku wskaźników) przez operator *.
W każdej kolekcji metoda begin() zwraca iterator wskazujący na jej pierwszy element oraz
metoda end() która wskazuje na miejsce po ostatnim elemencie.
Iteratorów używamy m. in. do:
-
Przeglądania elementów kolekcji, np. kod
set<int> s;
...
for(set<int>::iterator i=s.begin(); i++; i<s.end())
cout << *i;
wypisuje wszystkie elementy zbioru s.
-
Znajdowania elementów - funkcja find zwraca iterator wskazujący na odnaleziony element.
-
Usuwania elementów - funkcja erase usuwa element wskazany przez iterator.