A few words on C++ smart pointers.

Apr 09, 2016 16:55

Я досить часто зустрічаю думку що для написання безпечного з точки зору memory management коду на C++ треба його „обмазати“ std::shared_ptr. Мене ця точка зору дико бісить, бо насправді std::shared_ptr означає що у програміста просто не залишилось іншого виходу. std::shared_ptr дуже складна і доволі небезпечна штука, тому я вважаю що для використання саме цього smart pointer треба чітко розуміти його природу, призначення і вміти відповідати на наступні запитання:

Junior level:
  • Що таке std::smart_ptr?
  • Для чого він потрібен?
  • Які відносини між std::shared_ptr і std::weak_ptr?
  • Навіщо потрібен std::weak_ptr?
  • Чи можна вважати std::weak_ptr smart pointer?
  • Чи можна вважати std::weak_ptr вказівником?
  • Що ж тоді таке std::weak_ptr?

Middle level:
  • Що таке std::enable_shared_from_this?
  • Для чого він потрібен?
  • Як std::enable_shared_from_this взаємодіє з наслідуванням?

Senior/Lead/Architect level:
  • PIMPL і std::enable_shared_from_this - як їх помирити?

Насправді, у 80% випадків достатньо value/reference/std::unique_ptr. До речі, raw pointer, про який кажуть шо його ніколи-ніколи, навіть під дулом автомату не можна використовувати насправді можна використовувати для імітації maybe-семантики (коли std::/boost::optional з якихось причин не підходить). Нічого страшного у ньому немає. Треба просто запам'ятати кілька правил:

  1. Ссилка і вказівник не передають володіння (за винятком new, але від нього треба відмовлятись на користь std::make_shared/std::make_unique). Нам не треба хвилюватись про знищення ресурсу.
  2. Значення робить копію або передає володіння (якщо повертаємо локальний об'єкт із функції). Нам не треба хвилюватись про знищення ресурсу.
  3. std::unique_ptr передає володіння. Знищення ресурсу на нашій совісті (але std::unique_ptr потурбується про це).

Я стверджую що слідування цим правилам ніколи не призводить до проблем з пам'яттю і покриває 80% випадків, коли треба обирати вид smart pointer. Для 20% що залишились все ж доводиться використовувати std::shared_ptr. Один із таких випадків - Boost.ASIO. std::shared_ptr у цьому випадку не потрібен тоді і тільки тоді коли ваші об'єкти гарантовано живуть довше за boost::asio::io_service.

cpp, робота, програмування

Previous post Next post
Up