удалить или виртуальное удаление?
Вопрос
Я пишу библиотеку и демо-проект.Проекту все равно, какую версию библиотеки я использую (я могу использовать sdl, directx или что угодно еще в качестве серверной части gfx).Чтобы получить объект, я делаю
Obj *obj = libname_newDevice();
Теперь, должен ли я использовать delete или я должен сделать obj->deleteMe();
?Я спрашиваю, потому что я точно не создаю новое, поэтому я не должен выполнять удаление?
У меня есть obj->create(theType);
который возвращает класс с Obj-интерфейсом.Мой настоящий вопрос заключается в том, нужен ли мне libname_deleteDevice();
или есть obj->deleteMe()
нормально, так как у меня есть DeleteMe в интерфейсе?
Решение
Я бы сделал еще один шаг.
Если вы используете фабричную функцию для создания, может быть логично использовать фабричную функцию для уничтожения. В дополнение к этому, чтобы сделать все это приятным и безопасным, заверните в объект.
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.
Другие советы
Поскольку вы абстрагируете создание внутри libname_newDevice ()
(что я должен сказать, не очень хороший подход), вы должны уничтожить, используя что-то вроде libname_destroyDevice (obj)
. р>
И, как следует из комментария Мартина, лучше всего поместить их в конструктор и деструктор пользовательского класса, который вам просто нужно создать в стеке, а остальное позаботится компилятор.
Пожалуйста, попытайтесь прояснить свой вопрос.Мне это совершенно непонятно.
- Почему вы говорите о графическом интерфейсе?Имеет ли это отношение к данному вопросу?
- Вы спрашиваете, как вам следует проектировать свою библиотеку или как вы должны ее использовать?
Хорошей практикой является наличие фабрики объектов для создания объекта.Я предполагаю, что это роль libname_newDevice()
.
Библиотека также должна предоставлять способ удаления объекта (например, obj->DeleteMe()
или libname_Delete(obj)
).
Не полагайтесь на C++ delete
:вызывающий объект и библиотека могли быть скомпилированы с помощью другой версии компилятора, который выполнял бы разные действия в отношении распределения памяти и ресурсов.Поэтому будет безопаснее, если ваша библиотека удалит созданный ею объект.
Я думаю, что лучшим способом было бы соблюдать RAII и иметь некоторый объект-оболочку для подсчета ссылок (вы даже можете использовать shared_ptr с пользовательским посредником ). р>
Вы определенно не хотите реализовывать Obj :: deleteMe (). Это должно было бы сделать что-то вроде:
delete this;
пока вы еще были внутри этого -> deleteMe (). Следуйте совету Джейвокера и заставьте функцию уничтожения принять Obj * в качестве параметра.