C++/Шаблони проектування і структури даних/Контейнери

< C++

Контейнери

ред.

Контейнер - це клас, структура даних, або абстрактний тип даних, який дозволяє створювати колекції інших об'єктів. Іншими словами, контейнери застосовуються для зберігання об’єктів у вигляді організованої структури на основі конкретних правил збереження і доступу до елементів.

Контейнер для об'єктів різних типів

ред.

У C/C++ всі масиви є однорідними (тобто всі елементи є одного типу). Тим не менш, створивши додатковий шар логіки, можливо створити структуру, яка поводить себе як різнорідний (гетерогенний) контейнер (з об'єктами різних типів). Існує два випадки:

  • Перший виникає, коли всі об'єкти, які ви хочете зберігати в контейнері публічно успадковані від одного спільного базового класу. Тоді ви можете просто визначити свій контейнер, як набір посилань на базовий клас. Таким чином, в якості елементів, в контейнері будуть зберігатися посилання на різні об'єкти дочірніх класів, а звернення до них буде відбуватися за допомогою вказівників (користуючись поліморфізмом). Якщо необхідно дізнатися тип об'єкту в контейнері, можна використовувати dynamic_cast<> або typeid(). Вам ймовірно доведеться дізнатися про ідіому віртуального конструктора для того, щоб мати можливість копіювати контейнер об'єктів різних типів. Недоліком цього підходу є те, що це робить проблематичним управління пам'яттю (хто буде зберігати вказівник на об'єкти? Якщо видалити ці вказівники на об'єкти при знищенні контейнера, не можна бути впевненим, що хтось вивільнить пам'ять після об'єктів). Це також робить процедуру копіювання контейнеру досить складною.
  • Другий випадок виникає, коли всі об'єкти різнотипні — і вони не мають спільного базового класу. В такому випадку використовують класи-дескриптори, або як він ще називається – непрозорий вказівник (handle class, opaque pointer). Контейнер являтиме собою контейнер об'єктів дескрипторів (за значенням чи за посиланням). Кожен об'єкт знає як «тримати в собі» (іншими словами управляти вказівником) один об'єкт, який ви хочете помістити в колекцію. Ви можете використовувати один клас-дескриптор, з вказівниками на набір різних типів даних, або ієрархію класів, кожен з яких, може зберігати окремий тип з тих що ви бажаєте помістити в колекцію (в контейнері буде знаходитися базовий клас). Недоліком цього методу є те, що кожний раз коли вам треба змінити набір типів, які використовуються в конкретній задачі, вам слід змінювати код, який відповідає за набір типів, доступних для збереження в контейнері. Перевагою є те, що використовуючи класи-дескриптори, ви впорядковуєте всю роботу по управлінню пам'яттю і життєвим циклом об'єктів. [1]

Примітки

ред.
  1. [1] [34.1] [34.4] How can I build a <favorite container> of objects of different types?

Література

ред.
  1. Containers - cplusplus.com