2012-03-01 2 views
4

У меня есть класс C++, который реализует бинарный совместимый интерфейс (который будет использоваться как разделяемая библиотека), таким образом возвращая только типы C. строки как const char *, указатели void и указатели на другие классы с бинарным совместимым интерфейсом. Вопрос заключается в том, как я должен организовать управление памятью, должен ли я возвращать постоянные указатели на существующие данные класса (опасность использования устаревшего указателя пользователем) и сам выделять память или, скорее, указывать на некоторые переменные кучи и нести ответственность пользователя за удаление этих указателей позже или ??? Есть ли общие рекомендации для этого?Возврат указателей из класса. Кто несет ответственность за удаление?

+0

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

+0

Означает ли ваш код на C++ исключения? Он не может использоваться с C, если это так. – pmg

ответ

5

В «двоичном совместимом интерфейсе», используя интерфейс C, вы не принимаете общую кучу. Поэтому сторона, которая выделяет память из кучи, является стороной, которая возвращает ее в эту кучу.

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

+0

Действительно, я об этом не думал. – Slava

+0

В общем, я согласен, но он сказал, что он реализует «двоичный совместимый интерфейс», который, как я полагаю, означает существующий двоичный API.В этом случае он застрял в выполнении того, что указывает API; если он говорит, что другой объект отвечает за удаление выделенной вами памяти, вы должны позволить ему это сделать. –

+0

«Должен ли я ... заставить пользователя быть ответственным?» - Я пришел к выводу, что решение еще не принято. – MSalters

1

Сделать вызывающего абонента ответственным за выделение и освобождение памяти.

1

Оба они приняты и используются в производственных условиях, если они четко и тщательно документированы.

1

Это действительно зависит от вас.

Хороший объектно-ориентированный подход заключается в том, чтобы сам класс управлял памятью. Большая часть преимуществ ООП заключается в том, чтобы инкапсулировать функциональность как можно лучше. Таким образом, вы можете создать его так, чтобы код мог вызывать методы класса, не беспокоясь о том, как выделяется или освобождается память, потому что он управляется классом.

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

Все делается в обоих направлениях. Здесь нет настоящих жестких правил.

0

Если возможно, используйте интеллектуальные указатели, такие как unique_ptr или shared_ptr. (Что не должно быть проблемой, так как вы уже обертываете функции C, если я правильно вас понял.)

0

Я бы сказал, что вызывающий абонент несет ответственность за освобождение данных. Также обратите внимание, что вы не можете использовать new, если вызывающий объект не является приложением C++.

+1

Вы не можете использовать 'new', если вызывающий объект является приложением C++, скомпилированным с другим компилятором (версия). – MSalters

0

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

Смежные вопросы