У меня есть класс C++, который реализует бинарный совместимый интерфейс (который будет использоваться как разделяемая библиотека), таким образом возвращая только типы C. строки как const char *, указатели void и указатели на другие классы с бинарным совместимым интерфейсом. Вопрос заключается в том, как я должен организовать управление памятью, должен ли я возвращать постоянные указатели на существующие данные класса (опасность использования устаревшего указателя пользователем) и сам выделять память или, скорее, указывать на некоторые переменные кучи и нести ответственность пользователя за удаление этих указателей позже или ??? Есть ли общие рекомендации для этого?Возврат указателей из класса. Кто несет ответственность за удаление?
ответ
В «двоичном совместимом интерфейсе», используя интерфейс C, вы не принимаете общую кучу. Поэтому сторона, которая выделяет память из кучи, является стороной, которая возвращает ее в эту кучу.
Вы можете получить впечатляющие сбои и/или молчание, если вы выделяете блок из одной кучи, передаете его через интерфейс C, а затем имеете другую сторону delete
.
Действительно, я об этом не думал. – Slava
В общем, я согласен, но он сказал, что он реализует «двоичный совместимый интерфейс», который, как я полагаю, означает существующий двоичный API.В этом случае он застрял в выполнении того, что указывает API; если он говорит, что другой объект отвечает за удаление выделенной вами памяти, вы должны позволить ему это сделать. –
«Должен ли я ... заставить пользователя быть ответственным?» - Я пришел к выводу, что решение еще не принято. – MSalters
Сделать вызывающего абонента ответственным за выделение и освобождение памяти.
Оба они приняты и используются в производственных условиях, если они четко и тщательно документированы.
Это действительно зависит от вас.
Хороший объектно-ориентированный подход заключается в том, чтобы сам класс управлял памятью. Большая часть преимуществ ООП заключается в том, чтобы инкапсулировать функциональность как можно лучше. Таким образом, вы можете создать его так, чтобы код мог вызывать методы класса, не беспокоясь о том, как выделяется или освобождается память, потому что он управляется классом.
Тем не менее, бывают случаи, когда этот подход не работает, поскольку класс не знает, когда память больше не требуется. В этих случаях вы можете либо просто выделить вызывающего абонента память (а затем освободить ее), либо просто указать, что вызывающий должен освободить память, которая была выделена и возвращена из класса.
Все делается в обоих направлениях. Здесь нет настоящих жестких правил.
Если возможно, используйте интеллектуальные указатели, такие как unique_ptr или shared_ptr. (Что не должно быть проблемой, так как вы уже обертываете функции C, если я правильно вас понял.)
Я бы сказал, что вызывающий абонент несет ответственность за освобождение данных. Также обратите внимание, что вы не можете использовать new
, если вызывающий объект не является приложением C++.
Вы не можете использовать 'new', если вызывающий объект является приложением C++, скомпилированным с другим компилятором (версия). – MSalters
Если вы пишете существующий API, то вы делаете то, что требует API . У вас нет выбора в этом вопросе; API имеет значение , кто несет ответственность за что, а код с другой стороны API ожидает, что ваша реализация будет соответствовать.
- 1. Кто несет ответственность за удаление?
- 2. Кто несет ответственность за удаление фасета?
- 3. Кто несет ответственность за очистку?
- 4. Кто несет ответственность за развертывание?
- 5. Кто несет ответственность за точность?
- 6. Что несет ответственность за удаление моего указателя?
- 7. Кто несет ответственность за расшифровку видео?
- 8. Игры: Кто несет ответственность за отображение?
- 9. Кто несет ответственность за недостатки безопасности?
- 10. MVVM в iOS: кто несет ответственность за сборку?
- 11. MVP/MVVM - Фильтрация списков, кто несет ответственность?
- 12. DDD: Кто несет ответственность за создание объекта ценности и объекта?
- 13. Согласно шаблону MVVM - кто несет ответственность?
- 14. Кто несет ответственность за установку нулевого терминатора при обработке TB_GETBUTTONTEXT?
- 15. Кто несет ответственность за рассмотрение проблем, о которых сообщают клиенты
- 16. Кто несет ответственность за заполнение опций Zend_Form значениями базы данных?
- 17. JS/PHP: Кто несет ответственность за создание контента?
- 18. Кто несет ответственность за удаление выделенного кучи объекта при его перемещении?
- 19. Что несет ответственность за доступ Android-SQLite?
- 20. Что несет ответственность за освобождение объектов NSWindowController?
- 21. Кто несет ответственность за то, чтобы запрашивать страницы из ОС по мере роста стека?
- 22. Ответственность за создание объекта внутри класса
- 23. MVVM шаблон в javascript, который несет ответственность за то, что
- 24. MVVM - Решение, которое ViewModel несет ответственность за то, что
- 25. В Flux, что несет ответственность за прямой Разговаривая с API
- 26. Что на самом деле происходит и кто несет ответственность за вызов команды [] X?
- 27. Кто несет ответственность за то, чтобы управлять списком контроллеров/домовладельцев/хранилищем?
- 28. Кто несет ответственность за присоединение слушателей к схеме инъекций без инициализации?
- 29. Автоматическая настройка того, кто несет ответственность за изменение консоли в paper_trail в Heroku
- 30. В MVVM, кто несет ответственность за контроль над созданием новых представлений (текущий вид или его ViewModel)?
Это зависит, но вы действительно должны четко документировать это. Приоритет данных не является модульным свойством (и поэтому полезны алгоритмы сбора мусора). –
Означает ли ваш код на C++ исключения? Он не может использоваться с C, если это так. – pmg