|
0 / 0 / 0
Регистрация: 26.10.2015
Сообщений: 9
|
|
Фабрики и new/delete05.01.2016, 13:43. Показов 1491. Ответов 9
Метки нет (Все метки)
С++. Есть тяжёлый текстовый контейнер, который должен создаваться фабрикой (в моём случае это наверное Строитель), а в итоге будет передан в обработчик для проделывания там с ним всякого (readonly).
По идее же фабрики не хранят указатели на создаваемые в них объекты. То есть сделали new, выплюнули клиентскому коду и забыли, а там, где был запрос фабрике на создание, должен быть код на удаление. Но. Вот например сам контейнер. Сначала в кучу был залит сырой текст отдельным new. Потом другим new сделан пустой контейнер, которому в конструктор был передан указатель на сырой текст. А потом ведь фабрика выплёвывает контейнер на верх и отказывается от всех своих new. Это значит, что в контейнере, которому подкинули указатель на сырой текст, нужно сделать его удаление. А это выглядит подозрительно не здоровым. Тем более, что Макконнелл в Совершенном коде пишет, что надо удалять в той же области видимости, где было создано. Получается, что такой контейнер нельзя будет использовать отдельно от фабрики, ну или на свой страх и риск только. Как-то это не освещено в книжке банды GoF. Как быть?
0
|
|
| 05.01.2016, 13:43 | |
|
Ответы с готовыми решениями:
9
Используя delete по указателю, возвращенному new [] или delete [] указателем, возвращаемым new
|
|
Модератор
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,879
|
|
| 05.01.2016, 15:42 | |
|
Не понятно, какой смысл Вы вкладываете в "текстовый контейнер". Не похоже, что у Вас там вектор строк.
И что такое "сырой текст" и каким образом его залили в кучу - тоже непонятно. Гадать не хочется, а телепаты в отпуске.
0
|
|
|
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
|
|
| 05.01.2016, 16:04 | |
|
vipermagi, как было сказано выше, задача непонятна. Пока можно только сказать, что без острой необходимости не нужно управлять памятью вручную, для этого есть умные указатели.
0
|
|
|
0 / 0 / 0
Регистрация: 26.10.2015
Сообщений: 9
|
|
| 07.01.2016, 02:01 [ТС] | |
|
В текстовом контейнере содержится во-первых массив "сырого" UCS4-текста 4-байтных целых беззнаковых, во-вторых данные анализа, в-третьих итератор. На данный момент "сырой" текст просто грузится из файла. "Сырой" всмысле "raw". Сырее только массив байтов. Он даже на строки не разбит. Где-то сейчас читал, кто-то назвал такой текст "голый".
Есть некий менеджер, в котором происходит выбор какой будет реализация текстового контейнера. Менеджер получает свой готовый объект потому, как заказывал. А дальше, по логике, пользователю нужно с этим объектом работать. Это значит, что текстовый контейнер должен быть отдан менеджером в обработчик, которым будет управлять пользователь, и в котором будет происходить своя интерпретация всех действий с текстовым контейнером через итератор. С точки зрения менеджера и передачи в обработчик, здесь всё норм: менеджер удалит сам заказанный им текстовый контейнер после того, как обработчик закончит свои с ним дела. Но для вопроса задача не важна. Это вопрос в целом по фабричным паттернам, и даже, наверное, больше по Строителю. Я планирую в конечном варианте не руками из файла грузить текст, а программно динамически из базы, т.е. совсем без участия пользователя. Будет это отдельный фабричный класс, возвращающий наверх указатель на вектор 4-хбайтных чисел, как и в прототипе программы при простой загрузке руками пользователя. И так, вот менеджер заказывает у Строителя текстовый контейнер. Внутри строителя несколько последовательных этапов. Одним из этапов является создание объекта текстового контейнера с передачей в конструктор указателя на кусок "сырого" текста, который(указатель) только что был возвращён Строителю другим фабричным классом. То есть, одна фабрика создаёт "сырой" текст и передаёт владение другой фабрике, другая фабрика передаёт владение конечному контейнеру. С точки зрения фабрик всё в порядке, они не должны запоминать созданные объекты. Но с точки зрения дизайна класса контейнера, он становится испорченным. Ведь в его деструкторе по RAII должно быть удаление принятого в конструкторе объекта. Такой текстовый контейнер можно будет использовать только в фабриках. А в алгоритме, где надо только временно поместить указатель в контейнер, объект попадёт в чёрную дыру и будет сегфолт. Как спроектировать контейнер таким образом, чтобы он мог использоваться и для RAII с фабриками и обычным способом? Как сделать это всё более гибким? Принципы и паттерны проектирования они ведь именно про гибкость, а не про то, как сделать то, что очень очень хочется. 0x10, есть только std::auto_ptr, но если очень захотеть то и boost::shared_ptr. Смысл не в них. Смысл в том, что у меня аналог auto_ptr - это класс текстового контейнера. А он не просто оболочка для удаления, а полноценный класс. Смотришь вот на такой текстовый контейнер и совсем не ожидаешь, что это чёрная дыра для попадающих в него объектов.
0
|
|
|
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
|
||||||
| 08.01.2016, 10:14 | ||||||
|
Для простоты предлагаю начать рассуждать с функций. Обсуждение паттернов приводит к добавлению лишних терминов, несущих в себе дополнительную семантику, которая пока не нужна.
Итак, у нас есть две сущности: 1. Text. Сырой текст, блоб, данные. Может быть получен из разных источников. 2. ITextWrapper. Обертка над текстом, «контейнер». Обертка выбирается независимо от блоба. Разным оберткам можно подавать на вход текст с одинаковым содержимым, и они будут совершать над ним разные операции. Для каждой сущности нужна производящая функция: 1. Text* LoadText(); для загрузки текста из разных источников. 2. ITextWrapper* CreateWrapper(Text*); для оборачивания текста в «контейнер». Контрольная точка. До сих пор я все правильно понимаю? Проблема. Память для Text выделяется в функции LoadText. После чего владение на Text передается в ITextWrapper. И это кажется сложным для понимания и неудобным: управление памятью распределено по разным частям приложения. Хочется упростить. Контрольная точка. Правильно ли я понял проблему? Ключевой момент выше — это «передача владения». Это и реализуестя на умных указателях. Ниже пример (text заменено на более общее data)
1
|
||||||
|
306 / 101 / 18
Регистрация: 04.07.2014
Сообщений: 571
|
|
| 08.01.2016, 11:05 | |
|
0x10
Всё же, лучше никуда владение не передавать. Иначе потом начнут возникать проблемы... В одной библиотеке память выделили, а удалили в другой.
1
|
|
|
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
|
|
| 08.01.2016, 11:15 | |
|
mporro, да, и в этом случае опять же shared_ptr отработает нормально, т.к. по умолчанию освобождение памяти будет выполнено в той же единице трансляции, что и выделение.
0
|
|
|
0 / 0 / 0
Регистрация: 26.10.2015
Сообщений: 9
|
|
| 09.01.2016, 05:50 [ТС] | |
|
Точно ведь. Если через shared_ptr и делать new в его конструкторе, то можно потом в контейнер передавать тоже в shared_ptr на временную обработку. Тогда auto_ptr/unique_ptr здесь однозначно не подходят. Главное только не забыть, что shared_ptr нельзя инициализировать указателем при этом.
Вчера тоже читал, про корректную работу shared_ptr с библиотеками. Я ещё немного подумал, возможно мне будет лучше загружать "сырой" текст снаружи фабричного класса, и передавать его туда указателем. Так как от его содержимого не зависит остальное наполнение контейнера. И для контроля загрузки менеджером в будущем удобнее. Что, конечно, не отменяет решение shared_ptr для остальных объектов в куче, созданных внутри фабричного класса, строящего текстовый контейнер.
0
|
|
|
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
|
||
| 09.01.2016, 08:12 | ||
|
0
|
||
|
0 / 0 / 0
Регистрация: 26.10.2015
Сообщений: 9
|
|
| 11.01.2016, 13:33 [ТС] | |
|
0
|
|
| 11.01.2016, 13:33 | |
|
Помогаю со студенческими работами здесь
10
Чем отличается delete[] от delete? Паттерны проектирования (Фабрики) БД для мебельной фабрики Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
|
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу,
и светлой Луне.
В мире
покоя нет
и люди
не могут жить в тишине.
А жить им немного лет.
|
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила»
«Время-Деньги»
«Деньги -Пуля»
|
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
|
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога
Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога
Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
|
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
|
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога
Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
|