Дороговкази в c навіщо потрібні, коли використовувати і чим відрізняються від звернення до об'єкту безпосередньо

Але чи отримаємо ми виграш в швидкості, звертаючись безпосередньо до пам'яті?

Насправді, зовсім немає. Робота з покажчиками оформлена у вигляді купи, в той час як робота з об'єктами - це стек, простіша і швидша структура. Якщо ви новачок, то у нас для вас є матеріал, в якому ми детально розповідаємо, що таке стек і купа.

Строго кажучи, це питання об'єднує в собі два різних питання. Перший: коли варто використовувати динамічний розподіл пам'яті? Другий: коли варто використовувати покажчики? Природно, тут ми не обійдемося без загальних слів про те, що завжди необхідно вибирати найбільш підходящий інструмент для роботи. Майже завжди існує реалізація краще, ніж з використанням ручного динамічного розподілу (dynamic allocation) і / або сирих покажчиків.

динамічний розподіл

У формулюванні питання представлені два способи створення об'єкта. І основна відмінність полягає в терміні їх життя (storage duration) в пам'яті програми. Використовуючи Object myObject ;. ви покладаєтеся на автоматичне визначення терміну життя, і об'єкт буде знищений відразу після виходу з його області видимості. А ось Object * myObject = new Object; зберігає життя об'єкту до того моменту, поки ви вручну не видалите його з пам'яті командою delete. Використовуйте останній варіант тільки тоді, коли це дійсно необхідно. А тому завжди робіть вибір на користь автоматичного визначення терміну зберігання об'єкта, якщо це можливо.

Зазвичай примусове встановлення терміну життя застосовується в наступних ситуаціях:

  • Вам необхідно, щоб об'єкт існував і після виходу з області його видимості - саме цей об'єкт, саме в цій області пам'яті, а не його копія. Якщо для вас це не принципово (в більшості випадків це так), покладайтеся на автоматичне визначення терміну життя. Однак ось приклад ситуації, коли вам може знадобитися звернути до об'єкта поза ним області видимості, проте це можна зробити, не зберігаючи його в явному вигляді: записавши об'єкт в вектор, ви можете «розірвати зв'язок» з самим об'єктом - насправді він (а не його копія) буде доступний при виклику з вектора.
  • Вам необхідно використовувати багато пам'яті. яка може переповнити стек. Здорово, якщо з такою проблемою не доводиться стикатися (а з нею стикаються дуже рідко), тому що це «поза компетенцією» C ++, але на жаль, іноді доводиться вирішувати і цю задачу.
  • Ви, наприклад, точно не знаєте розмір масиву, який доведеться використовувати. Як відомо, в C ++ масиви при визначенні мають фіксований розмір. Це може викликати проблеми, наприклад, при зчитуванні призначеного для користувача введення. Покажчик же визначає тільки ту ділянку в пам'яті, куди буде записано початок масиву, грубо кажучи, не обмежуючи його розмір.

Якщо використання динамічного розподілу необхідно, то вам варто инкапсулировать його за допомогою розумного покажчика (що таке розумний покажчик можете прочитати в нашій статті) або іншого типу, що підтримує ідіому «Отримання ресурсу є ініціалізація» (стандартні контейнери її підтримують - це ідіома, відповідно до якої ресурс: блок пам'яті, файл, мережеве з'єднання і т.п. - при отриманні инициализируется в конструкторі, а потім акуратно знищується деструктором). Розумними є, наприклад, покажчики std :: unique_ptr і std :: shared_ptr.

Однак є випадки, коли використання покажчиків виправдано не тільки з точки зору динамічного розподілу пам'яті, але майже завжди є альтернативний шлях, без використання покажчиків, який вам і слід вибрати. Як і раніше, скажімо: завжди робіть вибір на користь альтернативи, якщо немає особливої ​​необхідності у використанні покажчиків.

Випадками, коли використання покажчиків можна розглядати як можливий варіант, можна назвати наступні: