Я в процессе переноса некоторого кода с Objective C на C ++. Я не так знаком с шаблонами проектирования C ++, как с Objective C. В мире какао существует очень распространенный шаблон написания фабричного метода, который возвращает "автоматически выпущенный" объект. Такие простые вещи, как:
- (MyClass *)load {
MyClass* obj = [[MyClass alloc] init];
return [obj autorelease];
}
Это просто и легко понять. Метод владеет памятью, которую он выделяет, но может вернуть ее вызывающей стороне, одновременно отказываясь от владения. Ему не нужно знать или заботиться о том, что вызывающий делает с этой памятью. Если он сохранит его, объект выживет. Если он полностью игнорируется, память будет освобождена через некоторое время после раскрутки текущего стека вызовов.
Я с некоторым трепетом подхожу к этому в C ++, потому что его среда без подсчета ссылок, похоже, не имеет ничего более чистого, чем autorelease
, или любой другой политики владения, которая также определены как таковые во фреймворках Какао. Каковы лучшие практики для этого типа шаблона в C ++?
Я знаю об auto_ptr, но есть также множество проблем с его использованием, и, похоже, он имеет слишком много недостатков, чтобы быть таким же повсеместным, как autorelease
(странная семантика копирования, отсутствие поддержки массивов, несовместимость с контейнерами STL и т. д.).
Интеллектуальные указатели Boost также являются очевидным кандидатом, а некоторые даже реализуют собственный подсчет ссылок. Мне кажется немного странным полагаться на стороннюю библиотеку для чего-то столь приземленного.
Другой вариант, который пахнет C, - это просто не освобождать возвращенную память, а указать через общепринятое соглашение об именах, что вызывающий теперь владеет возвращаемым объектом. Это кажется немного архаичным и подвержено невидимым утечкам, если вызывающий объект случайно проигнорирует возвращаемое значение.