Цель C "autorelease" в C ++ - стандартный способ управления временем жизни объекта? - PullRequest
5 голосов
/ 23 ноября 2011

Я в процессе переноса некоторого кода с Objective C на C ++.Я не так хорошо знаком с шаблонами проектирования C ++, как с Objective C. В мире Какао существует очень распространенный шаблон написания фабричного метода, который возвращает «автоматически выпущенный» объект.Что-то простое:

- (MyClass *)load {

    MyClass* obj = [[MyClass alloc] init];
    return [obj autorelease];
}

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

Я подхожу к этому с некоторым трепетом в C ++, потому что его не пересчитанная среда, кажется, не имеетчто-нибудь столь же чистое, как autorelease, или любой вид политики владения, который так же хорошо определен, как и в платформах Какао.Каковы лучшие практики для такого типа паттернов в C ++?

Я знаю об auto_ptr, но есть и множество проблем с его использованием, и, похоже, слишком много недостатков, чтобы быть столь же повсеместным, какautorelease (странная семантика копирования, отсутствие поддержки массивов, несовместимость с контейнерами STL и т. Д.).

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

Другой вариант, который пахнет C, - просто , а не освобождает возвращенную память,но при помощи общепринятого соглашения об именовании укажите, что вызывающий объект теперь владеет возвращаемым объектом.Это кажется немного архаичным и склонно к невидимым утечкам, если вызывающая сторона случайно проигнорирует возвращаемое значение.

Ответы [ 3 ]

8 голосов
/ 23 ноября 2011

«Лучшие практики» в мире C ++ 03 (то есть до C ++ 11) - это одна из двух вещей:

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

    Вот как, к сожалению, большое количество кода C ++ управляет памятью.Это может работать, пока все знают, что они должны делать и кто за что отвечает.

  2. Используйте некоторую форму интеллектуального указателя.std::auto_ptr странно, но это примерно так же легко, как в C ++ 03.Нет, вы не можете вставить их в стандартные контейнеры, но они определяют конкретную форму собственности.boost::shared_ptr является более эффективным и более полезным во многих других местах.

C ++ 11 предлагает std::unique_ptr, что по сути является «фиксированным» auto_ptr,Он опирается на возможности языка C ++ 11 (перемещение объектов), поэтому вы не можете просто написать его на C ++ 03.Вы можете хранить их в стандартных контейнерах и все.Но вы не можете просто передать их.Как следует из названия, они уникальны : может существовать только один из них, который указывает на этот объект.Когда этот unique_ptr уничтожен, он удаляет объект, на который ссылается.

Вы можете передать право собственности на unique_ptr только отдав его.То есть вы не можете делиться владением.Вы можете вернуть право собственности, что означает, что звонящий теперь владеет им.Вы можете передать владение другой функции, что означает, что эта функция принадлежит ей.Но никакие две сущности не могут владеть объектом через unique_ptr.

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

3 голосов
/ 23 ноября 2011

Я бы посмотрел на shared_ptr в ускорении.

Мир C ++ - это все о библиотеках. Поскольку никто не владеет C ++ (в отличие от Objective-C), он растет по мере того, как сообщество видит необходимость.

2 голосов
/ 23 ноября 2011

Ну, наиболее c ++-подобный вариант - использование умных указателей ..

Из того, что я прочитал, указатели подсчета ссылок - ваш лучший выбор, в стандарте c ++ 11 вы можете использовать shared_ptr

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...