Неправильный вопрос
В проекте C ++, в котором используются интеллектуальные указатели
Проблема на самом деле не имеет ничего общего с умными указателями. Речь идет только о собственности.
Умные указатели - это просто инструменты
Они ничего не меняют в отношении концепции собственности, особенно необходимость иметь четко определенное право собственности на вашу программу , тот факт, что право собственности может быть передано добровольно, но не может быть принято клиентом.
Вы должны понимать, что интеллектуальные указатели (также блокировки и другие объекты RAII) представляют значение и взаимосвязь, WRT это значение одновременно. shared_ptr
является ссылкой на объект и устанавливает связь: объект не должен быть уничтожен до этого shared_ptr
, и когда этот shared_ptr
уничтожен, если он является последним псевдонимом этого объекта, объект должен быть уничтожен немедленно. (unique_ptr
можно рассматривать как особый случай shared_ptr
, где по определению есть псевдонимы нуля, поэтому unique_ptr
всегда является последним псевдонимами объекта.)
Почему вы должны использовать умные указатели
Рекомендуется использовать умные указатели, потому что они много выражают только объявлениями переменных и функций.
Умные указатели могут выражать только четко определенный дизайн, они не устраняют необходимость определения владельца. Напротив, сборка мусора устраняет необходимость определять, кто отвечает за освобождение памяти. (Но не отнимайте необходимость определять, кто отвечает за очистку других ресурсов.)
Даже в не чисто функциональных языках сборки мусора вам необходимо четко указать владение: вы не хотите перезаписывать значение объекта, если другим компонентам все еще требуется старое значение. Это особенно верно в Java, где концепция владения изменяемой структурой данных чрезвычайно важна в многопоточных программах.
А как насчет сырых указателей?
Использование необработанного указателя не означает, что владения нет. Это просто не описывается объявлением переменной. Это можно описать в комментариях, в ваших проектных документах и т. Д.
Вот почему многие программисты на C ++ считают, что использование необработанных указателей вместо адекватного интеллектуального указателя уступает : потому что оно менее выразительное (я намеренно избегал терминов «хороший» и «плохой»). Я полагаю, что ядро Linux было бы более читабельным с несколькими объектами C ++ для выражения отношений.
Вы можете реализовать конкретный дизайн с умными указателями или без них. Реализация, которая использует умный указатель надлежащим образом, будет считаться превосходной для многих программистов на C ++.
Ваш реальный вопрос
В проекте C ++, какова хорошая философия дизайна в отношении использования "this"?
Это ужасно расплывчато.
Хранить необработанный указатель для дальнейшего использования опасно.
Зачем вам указатель для последующего использования?
Вы отказались от контроля над удалением объектов и доверяете ответственному компоненту сделать это в нужное время.
Действительно, некоторый компонент отвечает за время жизни переменной. Вы не можете взять на себя ответственность: она должна быть передана.
Если я когда-либо сохраню это в другой переменной или передам другой функции, которая потенциально может сохранить ее для дальнейшего использования, или свяжу с ней в обратном вызове, я создаю ошибки, которые появляются, когда кто-либо решает использовать мой класс.
Очевидно, что вызывающая сторона не проинформирована о том, что функция будет скрывать указатель и использовать его позже без контроля вызывающей стороны, вы создаете ошибки.
Решение, очевидно, либо:
- передать ответственность за управление временем жизни объекта на функцию
- гарантирует, что указатель сохраняется и используется только под контролем вызывающей стороны
Только в первом случае вы можете получить умный указатель в реализации класса.
Источник вашей проблемы
Я думаю, что ваша проблема в том, что вы стараетесь усложнить ситуацию с помощью умных указателей. Умные указатели - это инструменты, которые делают вещи проще, а не сложнее. Если умные указатели усложняют вашу спецификацию, переосмыслите вашу спецификацию с точки зрения более простых вещей.
Не пытайтесь вводить умные указатели в качестве решения, прежде чем у вас возникнут проблемы.
Вводите только умные указатели для решения конкретной четко определенной проблемы. Поскольку вы не описываете конкретную четко определенную проблему, невозможно обсудить конкретное решение (с использованием умных указателей или нет).