Тип std::string призначений для утримування рядків символів. Оголошення виглядає приблизно наступним чином:
typedef basic_string<char> string ;
Даний клас забезпечує функціональність подібну до інтерфейсу стандартних контейнерів, на прикладі std::vector або std::deque, але з деякою додатковою функціональністю, спеціалізованою для байтових символів. Як видно з оголошення, тип string являється спеціалізацією шаблонного класу basic_string для байтового типу символів char. Зверніть увагу на те, що об'єкти даного класу оперують своїми символами незалежно від їхного кодування - усі методи працюють з байтами значень.

Нутрощі класу

string () ;

/* конструктор копіювання */
string (const string& str) ;

/* підрядок */
string (const string& str, size_t pos, size_t len = npos) ;

/* копіювання послідовності */
string (const char* s) ;
string (const char* s, size_t n) ;

/* заповнення */
string (size_t n, char c) ;

/* послідовність будь-якого контейнеру */
template <class InputIterator>
string  (InputIterator begin, InputIterator end) ;
Конструктори класу. Параметр конструктору str призначений для вказування еталонного об'єкта, за образом якого буде конструюватися новий об'єкт класу std::string. Параметр конструктора pos призначений для вказування позиції, з якої буде виконуватися початок копіювання, а параметр len вказує кількість символів які будуть скопійованими. Копіювання відбувається поки не досягнеться len символів або доки не досягнеться кінець рядка. Параметр s призначений для вказування рядка в якості вказівника на масив символів (зазвичай, який повинен завершуватись символом з значенням 0 - нуль), які будуть копіюватися в новий об'єкт. Параметр n призначений для вказування кількості символів, які необхідно копіювати. Конструктор заповнення копіює вказаний символ c n кількість разів. Конструктор, який приймає ітератори begin i end копіює вміст, який розміщений у проміжку [begin, end) у новостворений об'єкт.
/* додавання рядка в кінець поточного */
string& append (const string& str) ;

/* підрядок */
string& append (const string& str, size_t subpos, size_t sublen) ;

/* копіювання з C-рядка символів */
string& append (const char* s) ;
string& append (const char* s, size_t n) ;

/* додавання символу с n разів */
string& append (size_t n, char c) ;

/* копіювання проміжку */
template <class InputIterator>
string& append (InputIterator begin, InputIterator end) ;
Даний метод додає новий вміст у кінець поточного об'єкта класу string. Параметр str призначений для передачі об'єкта цього класу, символи якого будуть копіюватись у кінець послідовності символів поточного об'єкта. Параметр subpos призначений для вказування позиції, з якої буде розпочинатись копіювання. Параметр методу sublen призначений для вказування кількості символів, які необхідно скопіювати. Параметр s вказує вказівник на масив символів вбудованого типу char (зазвичай закінчується символом з спеціальним значенням 0 - нуль, який вказує, що рядок закінчився). Параметр методу n вказує кількість символів, які потрібно скопіювати. Параметр c вказує значення символу, яке буде додаватись n разів у кінець поточного рядка. Ітератори begin i end призначені для вказування проміжку [begin, end), з якого будуть копіюватись значення і додаватись у кінець поточного рядка.
/* копіювання вмісту */
string& assign (const string& str) ;

/* підрядок */
string& assign (const string& str, size_t subpos, size_t sublen) ;

/* копіювання з буферу char */
string& assign (const char* s) ;
string& assign (const char* s, size_t n) ;

/* заповнення одним символом */
string& assign (size_t n, char c) ;

/* послідовність буь-якого контейнера */
template <class InputIterator>
string& assign (InputIterator begin, InputIterator end) ;
Даний метод замінює поточне значення об'єкта новим. Параметр str вказує на рядковий об'єкт, який виступає в образі еталона для даного об'єкту. Параметр subpos вказує на позицію, з якої починається копіювання з рядка str. Параметр sublen вказує на кількість символів, які користувач бажає скопіювати з рядка str. Параметр s передає вказівник на масив символів вбудованого типу char (який зазвичай повинен закінчуватись спеціальним символом з значенням 0 - нуль, що означає кінець рядка). Параметр n вказує на бажану кількість символів для копіювання. Параметр методу c вказує значення символу, яке буде вставлене в поточний об'єкт n разів. Параметри-ітератори begin i end призначені для обмеження послідовності [begin, end), яка буде копіюватись у об'єкт.
      char& at (size_t pos) ;
const char& at (size_t pos) const ;
Повертає посилання (reference) на символ.  Даний метод автоматично перевіряє коректність індексу символа pos, і якщо параметр некоректний відносно поточних меж об'єкта - генерує виключення out_of_range.
      iterator begin () ;
const_iterator begin () const ;
Повертає ітератор, який вказує на перший символ у об'єкті. Якщо об'єкт не містить символів, даний ітератор не повинен бути розйменованим (оператор *).
size_t capacity () const ;
Повертає кількість елементів, які може вмістити об'єкт, без перевиділення пам'яті.
void clear () ;
Очищує вміст об'єкта.
/* інший об'єкт string */
int compare (const string& str) const ;
int compare (size_t pos, size_t len, const string& str) const ;
int compare (size_t pos, size_t len, const string& str,
size_t subpos, size_t sublen) const ;

/* масиви C-рядків символів */
int compare (const char* s) const;
int compare (size_t pos, size_t len, const char* s) const;
int compare (size_t pos, size_t len, const char* s, size_t n) const ;
Порівнює вміст поточного об'єкта з об'єктом str або масивом символів s. Якщо метод повертає 0 (нуль) - рядки містять еквівалентні послідовності символів; при значенні менше нуля порівнюваний рядок являється меншим за поточний, або перший символ, який не співпав з поточним, менший за відповідний поточного; значення більше нуля означає, що усі символи співпали, але порівнюваний рядок являється більшим за поточний.
size_t copy (char* s, size_t len, size_t pos = 0) const ;
Копіює послідовність символів з вказаного рядка. Параметр s передає вказівник на рядок символів. Параметр len вказує на кількість символів, які необхідно скопіювати. Параметр pos призначений для вказування початкової позиції копіювання.
const char* c_str () const ;
Повертає вказівник на послідовність символів, яка розміщується в масиві вбудованого типу char, що закінчується символом з значенням нуля. Повернений рядок представляє поточне значення об'єкту. Метод корисний для передачі значень до стандартних функцій бібліотеки мови програмування C.
const char* data () const ;
Повертає вказівник на рядок символів, що представляє поточний вміст об'єкту. Не гарантується, що він закінчується термінальним нулем.
bool empty () const ;
Повертає true, якщо об'єкт не містить символів.
      iterator end () ;
const_iterator end () const ;
Повертає ітератор, який вказує на неіснуючий елемент, що стоїть після останнього елементу послідовності символів поточного об'єкту. Не повинен розйменовуватись.
/* видалення символу за позицією */
string& erase (size_t pos = 0, size_t len = npos);

/* видалення одного символу */
iterator erase (iterator p);

/* множина символів */
iterator erase (iterator begin, iterator end) ;
Видаляє обраний вміст з об'єкта. Параметр методу pos вказує на позицію символу, який необхідно видалити. Параметр len вказує на кількість символів, які необхідно видалити. Параметр p являється ітератором, який вказує на символ, що необхідно видалити. Параметри-ітератори begin i end призначені для вказування проміжку [begin, end), який необхідно видалити.
/* підрядок */
size_t find (const string& str, size_t pos = 0) const;

/* C-підрядок */
size_t find (const char* s, size_t pos = 0) const;

/* буфер */
size_t find (const char* s, size_t pos, size_t n) const ;

/* символ */
size_t find (char c, size_t pos = 0) const ;
Метод виконує пошук першого ходження елементів у об'єкті. Параметр str призначений для вказування об'єкта класу string, вміст якого повинен шукатися у поточному об'єкті. Параметр pos вказує від якої позиції повинен розпочатися пошук. Параметр s являється вказівником на масив символів типу char, вміст яких повинен шукатись у поточному об'єкті. Параметр n вказує розмір переданого масиву. Параметр c призначений для пошуку одного символу.
/* об'єкт */
size_t find_first_not_of (const string& str, size_t pos = 0) const;

/* буфер C-масиву символів */
size_t find_first_not_of (const char* s, size_t pos = 0) const;
size_t find_first_not_of (const char* s, size_t pos, size_t n) const ;

/* один символ */
size_t find_first_not_of (char c, size_t pos = 0) const ;
Метод знаходить перший елемент, який не вказаний у параметрах. Параметр str призначений для вказування послідовності символів за допомогою класу string. Параметр pos призначений для вказування позиції з якої буде розпочинатися пошук. Параметр s являється вказівником на масив символів. Параметр n вказує на розмір масиву. Параметр c призначений для пошуку невідповідного до даного елементу.
/* об'єкт символу */
size_t find_first_of (const string& str, size_t pos = 0) const ;

/* С-рядок */
size_t find_first_of (const char* s, size_t pos = 0) const ;
size_t find_first_of (const char* s, size_t pos, size_t n) const ;

/* один символ */
size_t find_first_of (char c, size_t pos = 0) const ;
Шукає перший з будь-якого вказаного символу, який міститься у рядку. Параметр str вказує на об'єкт який містить символи. Параметр pos призначений для вказування позиції, з якої повинен розпочинатись пошук. Параметр s являється вказівником на масив символів. Параметр n вказує на розмір буферу. Параметр c вказує символ, який необхідно знайти.
/* об'єкт класу */
size_t find_last_not_of (const string& str, size_t pos = npos) const ;

/* буфер C-масиву */
size_t find_last_not_of (const char* s, size_t pos = npos) const ;
size_t find_last_not_of (const char* s, size_t pos, size_t n) const ;

/* символ */
size_t find_last_not_of (char c, size_t pos = npos) const ;
Знайти останній символ, який не відповідає вказаним. Параметр str призначений для вказування символів для пошуку. Параметр s являється вказівником на масив символів. Параметр pos призначений для вказування позиції з якої повинен розпочинатися пошук. Параметр n призначений вказує на розмір буферу. Параметр c вказує на символ для пошуку.
size_t find_last_of (const string& str, size_t pos = npos) const ;

/* буфер з C-рядком */
size_t find_last_of (const char* s, size_t pos = npos) const ;
size_t find_last_of (const char* s, size_t pos, size_t n) const ;

/* один символ */
size_t find_last_of (char c, size_t pos = npos) const ;
Шукає останній символ з будь-яких вказаних у параметрах. Параметр str призначений для вказування символів у об'єкті класу string. Параметр pos вказує на позицію, з якої повинен розпочинатись пошук. Параметр s призначений для вказування C-рядка символів у вигляді масиву символів з термінуючим символом з значенням 0 (нуль). Параметр n призначений для вказування розміру буферу C-рядка. Параметр c призначений для вказування одного символу для пошуку.
allocator_type get_allocator () const ;
Повертає об'єкт, який призначений для створення нових примірників елементів класу.
/* з об'єкта */
string& insert (size_t pos, const string& str) ;

/* підрядок */
string& insert (size_t pos, const string& str, size_t subpos, size_t sublen) ;

/* C-рядок */
 string& insert (size_t pos, const char* s) ;
 string& insert (size_t pos, const char* s, size_t n) ;

/* заповнення */
 string& insert (size_t pos, size_t n, char c) ;
    void insert (iterator p, size_t n, char c) ;

/* один символ */
iterator insert (iterator p, char c) ;

/* множина елементів */
template <class InputIterator>
   void insert (iterator p, InputIterator begin, InputIterator end) ;
Метод призначений для вставки нових елементів або елемента перед вказаним. Параметр str призначений для вказування об'єкта, з якого будуть братись нові символи для вставки. Параметр s призначений для передачі вказівника на буфер C-символів у якості масиву char (останній зазвичай повинен мати нуль в якості останнього елемента, що вказує на кінець рядка). Параметр n призначений для вказування розміру буфера, або кількість повторень у версіях для заповнення. Параметр p являється ітератором і повинен вказувати на елемент, перед яким буде виконуватися вставка нових елементів. Параметр pos призначений для вказування індексу елемента, перед яким повинно виконуватися вставка нових елементів. Параметри ітератори begin i end призначені для обмеження проміжку [begin, end), який повинен бути скопійованим у поточний об'єкт.
size_t length () const ;
Повертає кількість байтів у рядку.
size_t max_size () const ;
Повертає максимально-можливий розмір рядка символів, яку може утримувати об'єкт класу string.
string& operator+= (const string& str) ;

/* додати вміст C-рядка */
string& operator+= (const char* s) ;

/* додати символ */
string& operator+= (char c) ;
Додає новий вміст до поточного вмісту об'єкта. Параметр str призначений для вказування об'єкта класу string, вміст якого буде повністю доданим до кінця поточного вмісту об'єкта. Параметр s являється вказівником на символьний C-рядок, який представляє собою масив символів типу char (і зазвичай закінчується нулем), вміст якого буде повністю скопійований у кінець поточного об'єкта. Параметр c призначений для вказування одиничного значення, яке буде доданим до поточного вмісту об'єкта.
/* об'єкт */
string& operator= (const string& str) ;

/* С-рядок */
string& operator= (const char* s) ;

/* символ */
string& operator= (char c) ;
Присвоює нове значення об'єкту, замінюючи його поточне значення. Параметр str призначений для вказування об'єкта класу string, з якого будуть копіюватись дані в поточний об'єкт. Параметр s призначений для вказування рядка символів у вигляді вказівника на масив символів байтового типу char (що має останнім символом значення нуля). Параметр c призначений для вказування одного байтового символа.
      char& operator[] (size_t pos) ;
const char& operator[] (size_t pos) const ;
Повертає посилання (reference) на байтовий символ за позицією pos поточного об'єкта. Доступ до неіснуючого елементу, який знаходиться поза межами послідовності об'єкта, спричиняє невизначену поведінку.
void push_back (char c) ;
Додає символ у кінець послідовності поточного об'єкта.
      reverse_iterator rbegin () ;
const_reverse_iterator rbegin () const ;
Повертає ітератор зворотнього перебору, який вказує на останній елемент послідовності. Якщо послідовність пуста, ітератор не повинен розйменовуватися.
      reverse_iterator rend () ;
const_reverse_iterator rend () const ;
Повертає ітератор зворотнього перебору, який вказує на неіснуючий елемент, що знаходиться перед першим символом об'єкта. Даний ітератор не повинен бути розйменованим.
/* інший об'єкт */
string& replace (size_t pos,  size_t len,  const string& str) ;
string& replace (iterator i1, iterator i2, const string& str) ;

/* підрядок string */
string& replace (size_t pos,  size_t len,  const string& str,
                 size_t subpos, size_t sublen) ;

/* буфер C-символів */
string& replace (size_t pos,  size_t len,  const char* s) ;
string& replace (iterator i1, iterator i2, const char* s) ;
string& replace (size_t pos,  size_t len,  const char* s, size_t n) ;
string& replace (iterator i1, iterator i2, const char* s, size_t n) ;

/* заповнення */
string& replace (size_t pos,  size_t len,  size_t n, char c) ;
string& replace (iterator i1, iterator i2, size_t n, char c) ;

/* проміжок символів */
template <class InputIterator>
  string& replace (iterator i1, iterator i2,
                   InputIterator begin, InputIterator end) ;
Замінює проміжок символів поточного об'єкта на нову послідовність. Параметри pos і len призначені для вказування проміжку для заміни новими символами у поточному об'єкті. Об'єкт str призначений для вказування джерела символів для заміни. Параметри subpos i sublen призначені для вказування пірядка у об'єкті str. Параметр s призначений для вказування джерела нових символів з області пам'яті в які розміщені послідовність байтових даних типу char. Параметр n вказує на розмір буферу s, або у випадку методу заповнення, кількість повторень заповнення символом c поточних символів об'єкта. Параметри-ітератори i1 i i2 призначені для обмеження проміжку [i1, i2) в поточному об'єкті, які будуть замінюватись новими значеннями. Параметри-ітератори begin i end призначені для вказування джерельного проміжку [begin, end) з якого будуть копіюватись символи у поточний об'єкт.
void reserve (size_t n = 0) ;
Метод змінює поточну внутрішню вмістимість об'єкта. Якщо параметр n менший за поточну вмістимість, метод може залишити її без змін. Даний метод не впливає на кількість, яку повертає метод length().
void resize (size_t n) ;
void resize (size_t n, char c) ;
Метод змінює розмір послідовності символів поточного об'єкта. Якщо параметр n являється меншим від поточної кількості елементів, послідовність зменшується з видаленням усіх символів, які стоять поза індексом n включно. Якщо параметр n більший за поточну кількість елементів у об'єкті - метод вставляє символи c, поки він не досягне рівня n.
/* об'єкт */
size_t rfind (const string& str, size_t pos = npos) const ;

/* C-рядок */
size_t rfind (const char* s, size_t pos = npos) const ;
size_t rfind (const char* s, size_t pos, size_t n) const ;

/* символ */
size_t rfind (char c, size_t pos = npos) const ;
Виконує пошук останнього входження шуканих символів. Параметр str призначений для передачі об'єкта класу string, який містить символи, які повинні шукатися у поточному об'єкті. Параметр pos призначений для вказування позиції з якої повинен розпочатись пошук. Параметр s являється вказівником на масив байтових символів char, які необхідно знайти в поточному об'єкті. Параметр n вказує на розмір буферу.
size_t size () const ;
Метод повертає кількість байтів, які присутні в об'єкті і які містять символи.
string substr (size_t pos = 0, size_t len = npos) const ;
Повертає новий примірник об'єкта класу string, який представляє підрядок поточного об'єкта, і який складається з символів, які починаються з позиції pos і закінчуються позицією за індексом len.
void swap (string& str) ;
Метод виконує обмін внутрішніми вказівниками і даними поточного об'єкта з вказаним об'єктом str. В результаті чого вміст об'єкта str присвоюється поточному об'єкту, а вміст поточного об'єкта присвоюється об'єкту str. Усі вказівники і ітератори залишаються валідними після виклику даного методу.
static const size_t npos ;
Константа містить максимальне значення типу site_t.

Приклади використання класу string

Приклад #1

Розглянемо простий приклад присвоєння, додавання і вставки значень в об'єкти класу string з використанням різних конструкторів класу.
#include <string> /* класу string i wstring */
#include <iostream> /* об'єкт cout */
using namespace std ; /* друкуємо усе без std */

/* головна функція програми */
int main (int argc, char** argv)
{
  /* створюємо перший рядок символів 
  ** і одразу ініціюємо його значення */
  string str1 = "Line of characters." ;
  
  /* створюємо примірник класу string 
  ** використовуючи конструктор копіювання */
  string str1_copy (str1) ;
  
  /* створюємо примірник класу string 
  ** з використанням конструтору для проміжку 
  ** символів, вказаного ітераторами */
  string str1_copy2 (str1.begin(), str1.end()) ;
  
  /* створюємо примірник рядкового класу 
  ** використовуючи перевантажений оператор +
  ** для даного типу і присвоюємо його значення 
  ** новому об'єкту */
  string str2 = "Some extra line, plus " + str1 ;
  
  /* створюємо пустий об'єкт класу string */
  string str3 ;
  
  /* присвоюємо нове значення об'єкту,
  ** використовуючи метод assign з об'єкту str2*/
  str3.assign (str2.begin(), str2.end()) ;
  
  /* збільшуємо розмір об'єкта str3, використовуючи 
  ** метод resize і вставляючи нові символи дієза у кінець 
  ** рядка */
  str3.resize (str3.size()+5, '#') ;
  
  /* збільшуємо розмір об'єкта класу str3 
  ** використовуючи метод insert, вставляючи
  ** нові примірники символу решітки у
  ** початок послідовності */
  str3.insert (str3.begin(), 5, '#') ;
  
  /* створюємо новий примірник класу string
  ** і присвоюємо його значення об'єкту str4 */
  string str4 = str2.substr (5, 10) ;
  
  /* виводимо значення усіх йменованих об'єктів
  ** у термінал */
  cout << "str1: " << str1 << endl
       << "str1_copy: " << str1_copy << endl
       << "str1_copy2: " << str1_copy2 << endl
       << "str2: " << str2 << endl
       << "str3: " << str3 << endl
       << "str4: " << str4 << endl ;
  
  return 0 ;
}
Вивід програми: cpp_std_string_sample1-cxx

Приклад #2

Розглянемо приклад використання методів пошуку класу std::string і стандартного алгоритму search з файлу algorithm.
#include <string> /* класу string i wstring */
#include <algorithm> /* алгоритм search */
#include <iostream> /* об'єкт cout */
using namespace std ; /* друкуємо усе без std */

/* головна функція програми */
int main (int argc, char** argv)
{
  /* створюємо піддослідний рядок символів 
  ** у якому будемо виконувати пошук */
  string str1 = "Line of some characters." ;
  
  /* створюємо інший примірник класу,
  ** який буде утримувати шукане значення */
  string search_str = "some" ;
    
  /* для наглядності, виводимо великий рядок у термінал */
  cout << "Original string: \"" << str1 << "\"" << endl ;
  
  /* використовуємо внутрішній метод find 
  ** для пошуку підрядка у рядку */
  size_t pos1 = str1.find (search_str) ;
  
  /* перевіряємо результат пошуку 
  ** і виводимо відповідне повідомлення */
  if (pos1 != str1.size())
  {
    /* коли знайшли */
    cout << "find str \"" << search_str << "\" at position " << pos1 << endl ;
  }
  else
  {
    /* при невдалому пошуку */
    cout << "didn`t find string \"" << search_str << "\"" << endl ;
  }

  /* виконуємо пошук підрядка стандартним методом search */
  string::iterator ster = search (str1.begin(), str1.end(),
                                  search_str.begin(), search_str.end()) ;

  /* перевіряємо результат пошуку 
  ** і виводимо відповідне повідомлення на екран */
  if (ster!=str1.end())
  { 
    /* за успіху */
    cout << "Algorithm search find substring!" << endl ;
  }
  else
  {
    /* при невдалому пошуку */
    cout << "Algorithm search didn`t find any match!" << endl ;
  }
  
  return 0 ;
}
Вивід програми: cpp_std_string_sample2-cxx

Приклад #3

Розглянемо приклад копіювання даних між контейнерами string і vector.
#include <string> /* класу string i wstring */
#include <vector> /* контейнер */
#include <iostream> /* об'єкт cout */
using namespace std ; /* друкуємо усе без std */

/* головна функція програми */
int main (int argc, char** argv)
{
  /* створюємо рядок символів 
  ** в масиві стандартного типу */
  const char* cptr = "Line of characters from embeded C-type const char*." ;
  /* визначаємо його довжину */
  int cLen = sizeof(*cptr)/sizeof(cptr[0]) ;
  
  /* заповняємо вектор даними */
  vector <char> vbuffer (cptr, cptr+cLen) ;
  
  /* створюємо рядковий об'єкт і
  ** присвоюємо йому значення з іншого типу
  ** контейнера за допомогою assign */
  string str1 ;  
  str1.assign (vbuffer.begin(), vbuffer.end()) ;
  
  /* створбюємо інший примірник класу string
  ** з використанням конструктору для проміжку 
  ** елементів з іншого типу контейнера */
  string str2 (vbuffer.begin(), vbuffer.end()) ;
  
  /* виводимо вміст об'єктів на екран */
  cout << "str1: " << str1 << endl ;
  cout << "str2: " << str2 << endl ;
  
  return 0 ;
}
Вивід програми: cpp_std_string_sample3-cxx

Приклад #4

Розглянемо приклад використання методів удаляння елементів з об'єкта. Організуємо видалення усіх примірників будь-якої букви.
#include <string> /* класу string i wstring */
#include <iostream> /* об'єкт cout */
using namespace std ; /* друкуємо усе без std */

/* головна функція програми */
int main (int argc, char** argv)
{
  /* створюємо піддослідний рядок символів */
  string str = "Example string for erasing it`s elements." ;
  
  /* виводимо його для наглядності на екран */
  cout << "Original: " << str << endl ;
  
  /* створюємо ітератор з класу string */
  string::iterator ster = str.begin();
  
  /* перебираємо у циклі усі значення контейнера 
  ** (лінійний пошук) */
  while (ster<=str.end())
  {
    /* якщо значення поточного символу еквівалентне 
    ** значенню символа пробілу */
    if (*ster==' ')
    {
      /* видаляємо його */
      str.erase (ster) ;
      /* припиняємо виконання поточної ітерації */
      continue ;
    }
    
    /* якщо символ має інше значення 
    ** переходимо до наступного */
    ++ ster ;
  }
  
  /* виводимо модифікований вміст об'єкту 
  ** у термінал */
  cout << "Modefied: " << str << endl ;
  
  return 0 ;
}
Вивід програми: cpp_std_string_sample4-cxx

Резюме

Отже клас string являється чудовим інструментом для виконання повсякденних завдань програмістом. Він набагато пришвидшує роботу, по відношенню з функціями роботи з рядками у мові програмування C (на подобі memset, strncpy, strncat і інші). Незамінимий клас для досягнення поставлених цілей.
Категорії: