М
Маша С++
@masha_cpp107 подп.
414просмотров
15 декабря 2025 г.
Score: 455
Давайте посмотрим на такой пример заголовочного файла (.h) c использованием указателя на incomplete тип (forward declaration): #include <memory> class ForwardDClass; class WithSmartPtr { public: WithSmartPtr() = default; ~WithSmartPtr() = default; private: ForwardDClass rawPtr_; //std::shared_ptr<ForwardDClass> sPtr_; //std::unique_ptr<ForwardDClass> uPtr_; }; int main(int argc, char argv<::>) { WithSmartPtr w; return 0; } Не будем вдаваться в корректность, посмотрим для начала на компилируемость. Такой код, конечно же соберется, ведь компилятор знает размер указателя в байтах (размер одинаков как для определенного, так и неопределенного типа). Если мы раскомментируем строку с shared_ptr, то код тоже скомпилируется (по крайней мере у меня собрался). Не будем говорить, про корректность его работы, но напомним, что вцелом удаление неопределенного типа - UB. А вот если мы раскомментируем строку с unique_ptr, то код перестанет собираться. Многие используют паттерн pimpl и потому знают, что реализацию деструктора нужно сделать в других исходниках (например .cpp), где forward declaration тип определен и проблема этим решается. Но почему компилятор не ругается на shared_ptr? Дело в том, что unique_ptr и shared_ptr требуют полного определения типа в разных местах. Детали сложны (и о них я не знаю), но первому нужен статический deleter, тогда как второму - динамический. Вывод: в нашей копилке костылей еще одно неправильное решение - заменить unique_ptr на shared_ptr 😊.
414
просмотров
1520
символов
Да
эмодзи
Нет
медиа

Другие посты @masha_cpp

Все посты канала →
Давайте посмотрим на такой пример заголовочного файла (.h) c — @masha_cpp | PostSniper