Цитата:
Сам по себе goto неплох, но вот
В принципе, я тоже начинаю так думать. В этих 2-х подходах есть такой момент: первый повторяет много одного и того-же кода - free(objI) повторяется много раз, а второй более компактный по размеру, но производит много лишних сравнений (if (objI) повторяется сначала перед goto, а потом - после _err), т.е., проигрывает по скорости, хотя, все эти лишние сравнения делаются только в том случае, если произошла ошибка при инициализации одного из объектов, а в таком случае, чаще всего, скорость уже некритична. Но goto - некрасивый подход, ИМХО.
Вот я и думаю, может, найдется третий, более элегантный вариант?
Цитата:
А где malloc?
malloc вызывается в функциях APIfunc1...APIfuncN(). На самом деле, это и не совсем malloс, так как возвращаются не указатели на объекты, а указатели на интерфейсы (т.е., например, IWebBrowser2* obj1), и это не совсем free, вызывается obj1->Release(), но суть от этого не меняется - в любом случае в конце нужно вызывать какую-то функцию, чтобы освободить эти объекты.
Кстати, на самом деле я еще немного протупил: метка _err должна стоять до return SOMETHING (сейчас опять исправил исходный пост), иначе все промежуточные объекты останутся в памяти. В некоторых языках (в Делфи, вроде бы) есть конструкция try ... catch ... finally, и как раз в блоке finally и выполняется работа по уничтожению всего, что должно быть уничтожено в любом случае, независимо от того, возникла ошибка или нет. Но в С++, почему-то, такой возможности не предусмотрели. Жаль.
Добавлено:
Цитата:
Можно так: указатели obj1, obj2,..., objN заносишь в массив, а с массивом всё компактней в цикле
Дык для инициализации каждого объекта вызывается своя функция, и все объекты при этом разнотипные.