C++. Клас vector. Методи, що визначають та змінюють загальні характеристики масиву

Клас vector. Методи, що визначають та змінюють загальні характеристики масиву


Зміст


Пошук на інших ресурсах:

1. Метод size(). Визначити розмір вектору

Поточну кількість елементів у динамічному масиві vector можна визначити з допомогою методу size(). Синтаксис оголошення методу size() наступний

size_t vector<T>::size() const

тут

  • T – тип елементів масиву.

Приклад.

// Деякий клас
class MyClass
{
  // ...
};

...

// Метод size()
// 1. Створити вектор з 5 чисел типу int та отримати його розмір
vector<int> A1(5);
int n1 = A1.size(); // n1 = 5

// 2. Створити вектор з 10 екземплярів типу MyClass 
// та отримати його розмір
vector<MyClass> A2(10);
int n2 = A2.size(); // n2 = 10

// 3. Створити пустий вектор типу bool та отримати його розмір
vector<bool>* A3 = new vector<bool>(); // створити через покажчик
int n3 = A3->size(); // n3 = 0

...

 

2. Метод max_size(). Максимально-допустимий розмір масиву

Метод max_size() дозволяє отримати максимально-допустиму кількість елементів масиву. Це значення залежить від типу елементів масиву vector. Для різних типів воно різне
В залежності від типу даних масиву vector, це значення може коливатись. Чим більше розмір даних кожного елементу масиву vector, тим менше значення max_size().
Синтаксис оголошення методу max_size() наступний:

size_t vector<T>::max_size() const

тут T – тип елементів динамічного масиву.

Приклад.

...

// Деякий клас
class Complex
{
public:
  double re;
  double im;

  // ...
};

...

// Метод max_size()
// 1. Створити вектор з 5 чисел типу int та отримати
// його максимально-допустимий розмір
vector<int> A1(5);
int max1 = A1.max_size(); // max1 = 1073741823

// 2. Створити вектор з 10 екземплярів типу Complex
// та отримати його максимально-допустимий розмір
vector<Complex> A2(10);
int max2 = A2.max_size(); // max2 = 268435455

// 3. Створити пустий вектор типу bool та отримати
// його максимально-допустимий розмір
vector<bool>* A3 = new vector<bool>(); // створити через покажчик
int max3 = A3->max_size(); // max3 = 2147483647
cout << max3 << endl;

...

 

3. Метод capacity(). Визначити розмір масиву з врахуванням зарезервованої пам’яті

Метод capacity() повертає кількість елементів, яка зарезервована (виділена) для масиву.

При додаванні нового елементу в масив, потрібно виділити додаткову пам’ять на 1 елемент більше. Однак, компілятор може збільшити розмір пам’яті на декілька елементів щоб при наступному додаванні ще одного елементу не виконувати повторно такі операції як звільнення пам’яті під попередньо створений масив, виділення нового фрагменту тощо. Таким чином прискорюється швидкодія.

Синтаксис оголошення методу наступний

size_t vector<T>::capacity<T> const

тут T – тип елементів масиву.

Приклад. У прикладі демонструється різниця між методами size() та capacity().

#include <iostream>
#include <vector>
using namespace std;

void main()
{
  // Метод capacity()
  // Створити масив з 10 елементів типу float
  vector<float> A1(10);

  // Вивести реальну кількість елементів масиву
  int capacity = A1.capacity();
  int size = A1.size();
  cout << "A1.capacity() = " << capacity << endl;
  cout << "A1.size() = " << size << endl;

  // Додати 1 елемент в кінець масиву
  A1.push_back(5);
  cout << "+1 item" << endl;

  // Вивести нові значення кількості елементів у масиві
  capacity = A1.capacity();
  size = A1.size();
  cout << "A1.capacity() = " << capacity << endl; // 15
  cout << "A1.size() = " << size << endl; // 11
}

Результат виконання програми

A1.capacity() = 10
A1.size() = 10
+1 item
A1.capacity() = 15
A1.size() = 11

Як видно з результату, при додаванні нового елементу, кількість елементів у масиві збільшилась на 1 і становить 11 (метод size()). Однак, сам розмір масиву збільшився на 5 елементів і становить 15 (метод capacity()). Тепер можна додавати ще 4 елементи без зайвого перерозподілу пам’яті. Якщо додавання елементів буде виконуватись у циклі, то такий підхід дозволить пришвидшити виконання програми.

 

4. Метод empty(). Визначити, чи пустий вектор

З допомогою методу empty() можна визначити, чи масив пустий (кількість елементів у масиві рівна 0).
Загальна форма методу empty() наступна:

bool vector<T> empty() const

тут T – тип елементів масиву.

Приклад.

#include <iostream>
#include <vector>
using namespace std;

void main()
{
  // Метод empty() - визначити чи пустий вектор
  vector<double> A(5); // Створити масив з 5 елементів

  // Перевірка, чи масив пустий
  if (A.empty())
    cout << "Vector A is empty." << endl;
  else
    cout << "Vector A is not empty." << endl;

  // Очистити масив
  A.clear();

  // Ще раз перевірити, чи масив пустий
  if (A.empty())
    cout << "Vector A is empty." << endl;
  else
    cout << "Vector A is not empty." << endl;
}

Результат виконання програми

Vector A is not empty.
Vector A is empty.

 

5. Метод shrink_to_fit(). Встановити розмір масиву на основі кількості елементів у ньому без додаткового резервування пам’яті

Метод shrink_to_fit() дозволяє вирівняти пам’ять, виділену (зарезервовану) для елементів масиву (метод capacity()) з пам’ятю, зайнятою елементами масиву (метод size()).
Кількість зарезервованих елементів (для яких виділена пам’ять) повертається методом capacity(). Кількість елементів, які визначені в масиві повертаються методом size(). Значення, що повертається методом capacity(), завжди більше або рівне значення, що повертається методом size().
Якщо значення, отримане методом capacity() більше за значення, отримане методом size(), то метод shrink_to_fit() дозволяє вирівняти ці значення. При цьому зменшується розмір пам’яті, що повертається методом capacity().
Метод є ефективний, коли в результаті різних операцій з масивом, залишається великий надлишок зарезервованих елементів у масиві.

Загальна форма методу наступна

void shrink_to_fit()

Після виклику цього методу, методи size() та capacity() завжди будуть повертати однакові значення.

Приклад.

#include <iostream>
#include <vector>
using namespace std;

void main()
{
  // Метод shrink_to_fit() - змінити значення зарезервованої пам'яті для масиву
  // 1. Створити масив цілих чисел на основі списку ініціалізації
  initializer_list<int> L = { 1, 2, 3, 4, 5 };
  vector<int> A1(L);

  // 2. Вивести кількість елементів,
  // для яких вже розподілена пам'ять
  cout << "Allocated size = " << A1.capacity() << endl; // 5

  // 3. Вивести поточну кількість елементів
  cout << "Size = " << A1.size() << endl; // 5

  // 4. Додати до масиву 1 елемент
  A1.push_back(6);
  cout << "+1 item" << endl;

  // 5. Ще раз вивести розподілену кількість елементів
  // та поточну кількість елементів
  cout << "Allocated size = " << A1.capacity() << endl; // 7
  cout << "Size = " << A1.size() << endl; // 6

  // 6. Вирівняти розподілену кількість з поточною кількістю
  A1.shrink_to_fit();
  cout << "shrink_to_fit()" << endl;

  // 7. Повторно вивести розподілену та фактичну кількості елементів
  cout << "Allocated size = " << A1.capacity() << endl; // 6
  cout << "Size = " << A1.size() << endl; // 6
}

Результат виконання програми

Allocated size = 5
Size = 5
+1 item
Allocated size = 7
Size = 6
shrink_to_fit()
Allocated size = 6
Size = 6

Як видно з результату, після додавання елементу в масив, розмір масиву збільшився з 5 до 6. Це є природньо і метод size() це показав. Але реальний розмір масиву збільшився з 5 до 7, про що показав метод capacity(). Тобто, виділилось на 1 елемент більше.
Виклик методу shrink_to_fit() перерозподілив пам’ять так, що кількість виділеної пам’яті під елементи стала рівна кількості пам’яті, зайнятої елементами.

 

6. Метод resize(). Змінити розмір масиву

Метод resize() дозволяє змінювати розмір динамічного масиву у більшу або в меншу сторону. Метод має дві перевантажені реалізації.
Перша реалізація має наступне оголошення

void resize(const size_t _NewSize)

тут

  • _NewSize – новий розмір масиву. Якщо _NewSize більше поточного розміру масиву, то всі інші елементи доповнюються нульовими значеннями.

Друга реалізація має наступне оголошення

void resize(const size_t _NewSize, const T& Val)

тут

  • _NewSize – новий розмір масиву;
  • T – тип елементів масиву;
  • Val – значення, яким доповнюються елементи масиву у випадку, якщо значення _NewSize більше поточного розміру.

Приклад.

...

// Метод resize() - змінити розмір масиву
// 1. Створити масив цілих чисел на основі списку ініціалізації
initializer_list<int> L = { 1, 2, 3, 4, 5 };
vector<int> A1(L);

// 2. Змінити розмір масиву A1
A1.resize(8); // A1 = { 1, 2, 3, 4, 5, 0, 0, 0 }

// 3. Зменшити розмір масиву A1 з заповненням значеннями 10
A1.resize(6, 10); // A1 = { 1, 2, 3, 4, 5, 0 }

// 4. Збільшити розмір масиву A1 з заповненням значеннями 15
A1.resize(9, 15); // A1 = { 1, 2, 3, 4, 5, 0, 15, 15, 15 }

...

 

7. Метод reserve(). Зарезервувати додаткову пам’ять для елементів масиву

Метод reserve() дозволяє виділити (зарезервувати) додаткову пам’ять для елементів масиву, яка повертається методом capacity(). Реальна кількість елементів у масиві, яка повертається методом size(), не змінюється.
Правильне використання методу у програмі дозволяє пришвидшити виконання програми у випадках, коли активно змінюється розмір масиву (часто виконуються операції додавання, видалення елементів з масиву). Це здійснюється за рахунок зменшення кількості операцій, пов’язаних з перерозподілом пам’яті.

Оголошення методу наступне

void reserve(size_t Newcapacity)

тут

  • Newcapacity – новий розмір масиву з урахуванням зарезервованих елементів.

Приклад.

#include <iostream>
#include <vector>
using namespace std;

void main()
{
  // Метод reserve() - зарезервувати додаткову пам'ять для масиву
  // 1. Оголосити масив з 5 елементів типу float
  vector<float> A(5);

  // 2. Вивести кількість елементів масиву та зарезервовану кількість елементів
  cout << A.size() << endl; // 5
  cout << A.capacity() << endl; // 5

  // 3. Зарезервувати додаткову пам'ять для масиву
  A.reserve(12);

  // 4. Вивести кількість елементів масиву та зарезервоване місце для елементів масиву
  cout << A.size() << endl; // 5
  cout << A.capacity() << endl; // 12
}

Результат виконання програми

5
5
5
12

 


Споріднені теми