Передача недавно выделенных данных непосредственно к функции

Az Login - это команда из интерфейса командной строки Azure, поэтому для запуска этого интерфейса необходимо установить интерфейс командной строки на компьютере, на котором он запущен. CLI не будет установлен в веб-приложении Azure.

Если вы пишете веб-приложение .net, вы действительно хотите использовать .net Azure API для прямой связи с API-интерфейсом REST Azure, не пытаясь использовать CLI.

5
задан Cristián Romo 29 December 2008 в 20:16
поделиться

8 ответов

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

Существуют многочисленные проблемы с Вашим кодом:

  • Прежде всего, кто владеет указателем? Кто ответственен за освобождение его? Код вызова не может сделать этого, потому что Вы не храните указатель. Это означает, что вызванная функция должна сделать это, но это не ясно кому-то смотрящему на ту функцию. Точно так же, если я назову код от где-то в другом месте, то я, конечно, не ожидаю, что функция для вызова удаляет на указателе, который я передал ему!
  • Если мы делаем Ваш пример немного более сложным, он может пропустить память, даже если названные вызовы функции удаляют. Скажите, что это похоже на это: functionCall(new className(initializers), new className(initializers)); Предположите, что первый выделяется успешно, но второй выдает исключение (возможно, это вне памяти, или возможно конструктор класса выдал исключение). functionCall никогда не называют затем и не может освободить память.

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

className* p = new className(initializers);
functionCall(p);
delete p;

Но это - все еще путаница. Что, если functionCall выдает исключение? Затем p не будет удален. Если мы не добавляем попытку/выгоду вокруг всего этого, но sheesh, это грязно. Что, если функция становится немного более сложной, и может возвратиться после functionCall, но прежде удаляет? Возгласы, утечка памяти. Невозможный поддержать. Плохой код.

Таким образом, одно из хороших решений состоит в том, чтобы использовать интеллектуальный указатель:

boost::shared_ptr<className> p = boost::shared_ptr<className>(new className(initializers));
functionCall(p);

Теперь с владением памяти имеют дело. shared_ptr владеет памятью и гарантирует, что она будет освобождена. Мы могли использовать std::auto_ptr вместо этого, конечно, но shared_ptr реализует семантику, которую Вы обычно ожидали бы.

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

Интеллектуальные указатели обычно являются абсолютным минимумом, необходимо обработать управление памятью. Но часто, хорошее решение состоит в том, чтобы записать Ваш собственный класс RAII.

className должен быть выделен на стеке, и в его конструкторе, сделать что выделения с new необходимы. И в его деструкторе, это должно освободить ту память. Таким образом, Вам гарантируют это, никакие утечки памяти не произойдут, и можно сделать вызов функции настолько простым:

functionCall(className(initializers));

Библиотека стандарта C++ работает как это. std::vector один пример. Вы никогда не выделяли бы вектор с new. Вы выделяете его на стеке и позволяете ему иметь дело со своими выделениями памяти внутренне.

12
ответ дан 18 December 2019 в 06:04
поделиться

Да, пока Вы освобождаете память в функции. Но ни в коем случае это не лучшая практика для C++.

6
ответ дан 18 December 2019 в 06:04
поделиться

Это зависит.

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

5
ответ дан 18 December 2019 в 06:04
поделиться

Это будет работать на объекты, созданные на стеке, но не регулярном указателе в C++.

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

0
ответ дан 18 December 2019 в 06:04
поделиться

Безопасно, если функция, которую Вы вызываете, имеет семантику принятия владения. Я не вспоминаю время, где мне было нужно это, таким образом, я буду считать это необычным.

Если функция прокладывает себе путь, она должна взять свой аргумент в качестве объекта интеллектуального указателя так, чтобы намерение было clea; т.е.

void functionCall(std::auto_ptr<className> ptr);

вместо

void functionCall(className* ptr);

Это делает передачу права собственности явной, и функция вызова избавится от памяти, на которую указывает ptr, когда выполнение функции упадет из объема.

1
ответ дан 18 December 2019 в 06:04
поделиться

В C++ мы не создали бы память динамично как этот.
Вместо этого Вы создали бы временный объект стека.

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

// No need for new or memory management just do this
functionCall(className(initializers));

// This assumes you can change the functionCall to somthing like this.
functionCall(className const& param)
{
    << Do Stuff >>
}

Если Вы хотите передать не ссылку константы, затем делают это как это:

calssName tmp(initializers);
functionCall(tmp);

functionCall(className& param)
{
    << Do Stuff >>
}
3
ответ дан 18 December 2019 в 06:04
поделиться
0
ответ дан 18 December 2019 в 06:04
поделиться

В целом, нет, если Вы не хотите пропустить память. На самом деле, в большинстве случаев, это не будет работать, начиная с результата

new T();

в C++ T*, не T (в C#, новый T () возвращает T).

0
ответ дан 18 December 2019 в 06:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: