Ответ
В C++ указатели — это мощный, но требующий аккуратности инструмент для работы с памятью и полиморфизмом. Вот их основные виды:
*1. Сырые (raw) указатели (`T`):** Базовый тип, хранящий адрес памяти. Не управляют временем жизни объекта.
int value = 10;
int* raw_ptr = &value; // Указатель на int
*raw_ptr = 20; // Разыменование и изменение значения
2. Умные указатели (smart pointers):
Классы из <memory>, которые автоматически управляют временем жизни динамически выделенных объектов.
std::unique_ptr<T>: Выражает эксклюзивное владение. Невозможно скопировать, только переместить. Объект уничтожается при разрушенииunique_ptr. Идеален для владения ресурсом в области видимости.auto uptr = std::make_unique<MyClass>(args); // Предпочтительный способ создания // uptr автоматически удалит объект при выходе из области видимостиstd::shared_ptr<T>: Разделяемое владение с подсчетом ссылок (reference counting). Объект уничтожается, когда последнийshared_ptrна него разрушается.auto sptr1 = std::make_shared<MyClass>(); auto sptr2 = sptr1; // Оба shared_ptr владеют одним объектомstd::weak_ptr<T>: «Слабая» ссылка на объект, управляемыйshared_ptr. Не увеличивает счетчик ссылок. Используется для разрыва циклических зависимостей и безопасного доступа к объекту, который может быть уже удален.std::weak_ptr<MyClass> wptr = sptr1; if (auto temp_ptr = wptr.lock()) { // Попытка получить shared_ptr // Объект еще жив, можно использовать temp_ptr }
3. Указатели на функции и члены класса:
- Указатель на функцию:
ReturnType (*func_ptr)(ParamTypes) = &function_name; - Указатель на член данных:
Type ClassName::*ptr = &ClassName::member; - Указатель на метод:
ReturnType (ClassName::*method_ptr)(Params) = &ClassName::method;
4. Ссылки (T& и const T&):
Хотя технически это не указатели, они семантически похожи на константные указатели, которые всегда разыменованы и не могут быть null. Более безопасная альтернатива указателям, когда null-значение не требуется.
Правило сегодняшнего дня: В современном C++ сырые указатели следует использовать только для наблюдения (non-owning pointers), без передачи владения. Все владение динамической памятью должно быть выражено через умные указатели (unique_ptr по умолчанию, shared_ptr при необходимости разделяемого владения). Это предотвращает утечки памяти и ошибки двойного удаления.