Удалить или виртуальное удаление?

Пишу библиотеку и демонстрационный проект. Проекту все равно, какую версию библиотеки я использую (я могу использовать sdl, directx или все, что мне нравится в качестве бэкэнда gfx). Чтобы получить объект, я делаю

Obj *obj = libname_newDevice();

Теперь я должен использовать удаление или мне следует сделать obj->deleteMe();? Я спрашиваю, потому что я точно не делаю нового, поэтому мне не следует делать удаление?

У меня есть obj->create(theType);, который возвращает класс с интерфейсом Obj. Мой реальный вопрос: нужен ли мне libname_deleteDevice(); или obj->deleteMe() в порядке, так как у меня есть 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
1 027
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Поскольку вы абстрагируете создание внутри libname_newDevice() (что, я должен сказать, не очень хороший подход), вам следует уничтожить, используя что-то вроде libname_destroyDevice (obj).

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

Да, симметрия - это хорошо. Затем вы должны обернуть все это внутри объекта, где эти две функции вызываются конструктором / деструктором.

Martin York 12.11.2008 20:11

Пожалуйста, попробуйте прояснить свой вопрос. Мне это совершенно непонятно.

  • Почему вы говорите о графической серверной части? Имеет ли это отношение к вопросу?
  • Вы спрашиваете, как создать свою библиотеку или как ее использовать?

Хорошая практика - иметь фабрику объектов для создания объекта. Я предполагаю, что это роль libname_newDevice().

Библиотека также должна обеспечивать способ удаления объекта (например, obj->DeleteMe() или libname_Delete(obj)).

Не полагайтесь на C++ delete: вызывающий объект и библиотека могли быть скомпилированы с другой версией компилятора, который будет делать разные вещи в отношении распределения памяти и ресурсов. Поэтому безопаснее, если ваша библиотека удалит созданный ею объект.

Думаю, графика не актуальна. В частности, я хочу знать, следует ли мне выполнять libname_Delete () или делать obj-> DeleteMe (); У меня также есть obj-> create (theType);

user34537 12.11.2008 20:01

Безопаснее (в Windows), если библиотека удаляет созданные ею объекты. Но ваши аргументы в пользу этого ошибочны.

Martin York 12.11.2008 21:08

Вы определенно не хотите реализовывать Obj :: deleteMe (). Это должно было бы сделать что-то вроде:

delete this;

пока вы все еще были внутри this-> deleteMe (). Следуйте предложению Jaywalker'а и заставьте функцию destroy использовать Obj * в качестве параметра.

"удалить это;" может вызвать мурашки по коже, но это не обязательно плохо. Объекты, которые реализуют собственный подсчет ссылок, всегда должны это делать. Примеры см. В разделе Release () в каждой «моей первой реализации COM».

RobH 13.11.2008 19:22

Я думаю, что лучше всего было бы соблюдать RAII и иметь некоторый объект-оболочку для подсчета ссылок (вы даже можете использовать shared_ptr с настраиваемым освободителем).

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

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

class ObjWrap
{
    public:
        ObjWrap()
            :obj(libname_newDevice())
        {}
        ~ObjWrap()
        {    libname_deleteDevice(obj);}
    private:
        ObjWrap(ObjWrap const&);        // Dont copy
        void operator=(ObjWrap const&); // Dont copy
        Obj* obj;
}; // If you want to copy then you need to extra work on ref counting
   // This may need some form of smart pointer.

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