Удалить или не удалять (вызовите func)?

Я помню, как кто-то сказал, что если вы создаете класс через библиотеку, вы должны уничтожить его через библиотеку. Итак, означает ли это, что мне не следует вызывать удаление? Я должен вместо этого вызвать в myclass.deleteMe()? Решит ли проблему перегрузка с удалением?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
395
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Проблема с удалением вашим приложением того, что было создано в библиотеке, заключается в том, что библиотека может использовать другой диспетчер кучи / памяти.

Решения включают:

  • Убедитесь, что ваше приложение построено с тем же менеджером кучи, что и библиотека.
  • Реализуйте (не встроенный) метод deleteMe в классе, реализация которого может быть delete this;.
  • Определите пользовательский operator delete в классе, реализованном в библиотеке ... если есть пользовательский оператор delete, он будет вызываться, если и когда ваше приложение удалит часть объекта.

Я изучаю 3-е решение. Я не знаю способа гарантировать, что библиотека и приложение (оба мои) созданы с совместимыми настройками кучи. Третий вариант звучит более естественно, как delete obj; инстинктивно это то, что кто-то делает вместо того, чтобы проверять наличие deleteMe или какой-либо функции удаления.

user34537 03.01.2009 21:45

Вы сказали: «Я не знаю способа гарантировать, что библиотека и приложение (оба мои) созданы с совместимыми настройками кучи». ... какой компилятор и какую ОС вы используете, и является ли ваша библиотека статической или динамической?

ChrisW 03.01.2009 23:10

I remember someone saying if you create a class through a lib you should destroy it through the lib.

Это означает, что если вы вызываете функцию в библиотеке для создания объекта для вас, вы должны прочитать документацию этой функции, в которой должно быть указано, как вы снова освободите этот объект. Часто функция бесплатно что-то называется аналогично функции распределения. Например, библиотека pcre имеет две функции: pcre_malloc и pcre_free.

Причина в том, что библиотека выделяет ресурсы непрозрачным для вас образом (именно поэтому вы в первую очередь используете эту функцию). Он может получить память из раздела данных программы, в то время как вы (ошибочно) предположите, что он получил память, возможно, из кучи при использовании delete.

Если этот писатель библиотеки ты, применяются те же правила. Убедитесь, что когда одна из ваших функций возвращает динамически выделенный объект, вы говорите, как вызывающий должен его обработать.

  1. Инкапсулирован ли объект в интеллектуальный указатель? Затем интеллектуальный указатель позаботится о вызове соответствующего удалитель, который вы указали.
  2. Вы возвращаете необработанный указатель? Вам следует избегать этого, потому что вызывающая сторона должна отслеживать указатель, а вызывающая сторона должна будет передать указатель в документ функции ты в вашем интерфейсе. Это просто еще один уровень зависимости, которую вы возлагаете на пользователя вашей библиотеки, которую интеллектуальные указатели могут элегантно рационализировать.
  3. Вы возвращаете объект по значению, которое само по себе является оболочкой для выделенного ресурса? В этом случае перегрузите конструктор копирования, оператор присваивания копии и деструктор класса этого объекта, который затем управляет ресурсом, либо копируя его должным образом, либо разделяя его между всеми другими экземплярами своего объекта (см. этот ответ).

Вы почти никогда не должны перегружать оператор удаления для вашего класса пока не, вы также перегрузили новый оператор. Перегрузка оператора удаления не должна восприниматься буквально: это означает, что вы просто перегружаете освобождение связанной памяти объекта. Это имеет смысл только в том случае, если вы размещаете свой собственный пул памяти или хотите регистрировать каждое выделение / освобождение памяти для ваших объектов.

я пишу эту библиотеку. Я в основном хочу знать, лучше ли перегрузка оператора удаления или что-то еще, например, deleteMe () в виртуальном классе.

user34537 03.01.2009 21:42

Это правило применяется к классам, разрабатываемым Ты. Практическое правило (хотя и не всегда используется) состоит в том, что если класс создает объект, он должен его удалить.

Но если вы спрашиваете о какой-то библиотеке, разработанной кем-то другим, вы не можете знать, соблюдал ли он это правило, и вам нужно проверить это через himselef / documentation / code.

Вы должны проконсультироваться с документацией библиотеки, чтобы узнать, как удалять созданные ею объекты. Помимо того, что упоминали другие, иногда библиотека ожидает, когда объекты будут удалены. Например, в wxWidgets вы не должны удалять виджеты самостоятельно, потому что wxWidgets попытается удалить их за вас, когда их родительский виджет будет уничтожен - если вы уже удалили их, то у вас есть двойное освобождение (неопределенное поведение). Невозможно определить это, просто взглянув на типы - библиотеки могут работать таким образом, даже если они не возвращают интеллектуальный указатель. Кроме того, библиотека может зависеть от освобождений, происходящих в определенном порядке (например, может быть, она всегда освобождает все объекты одного типа перед другим), а удаление вещей самостоятельно нарушает порядок.

Если ваша библиотека предоставляет определенный метод для создания объектов с точки зрения менеджеров памяти и т. д., Тогда у вас должен быть способ нет, чтобы избавиться от этого объекта, за исключением значимого способа, который бы избавлялся от объекта аналогично тому, как он был построен / выделен.

Другими словами, если ваши объекты склонны выделяться определенным образом, убедитесь, что все способы избавления от них соответствуют вашим «определенным способам».

Другие вопросы по теме