Задать вопрос

Правильно понимаю из статьи про умные указатели?

Читаю статью Умные указатели в современном C++ с точки зрения н...
В разделе Рациональное обоснование std::make_unique и std::make_shared приведён текст:

Во-вторых, это делает ваш код защищенным от исключений. Рассмотрим вызов функции, принимающей на вход два умных указателя, следующим образом:
void function(std::unique_ptr<A>(new A()), std::unique_ptr<B>(new B())) { ... }

Предположим, что new A() выполняется успешно, но new B() выбрасывает исключение: вы ловите его, чтобы возобновить нормальное выполнение программы. К сожалению, стандарт C++ не требует, чтобы объект A был уничтожен, а его память высвобождена: память тихо утекает, и нет способа ее очистить.

Возникло несколько связанных вопросов:
1. Это ведь вызов функции, а написано частично как определение функции с void и фигурными скобками. Тут ошибка оформления? Или (сильно сомневаюсь) это действительно определение ф-ии и можно написать определение функции с new в списке аргументов?
2. Если ответ на вопрос 1. что есть ошибка оформления и это действительно вызов ф-ии.
Почему при исключении, объект A не будет удалён? Ведь чуть позже произойдёт в любом случае выход из текущей области видимости, и умный указатель удалится, очистив память. Или я чего-то упустил и по стандарту (рассматриваем C++11) возможно выполнение в порядке new A, затем сразу без создания временного объекта std::unique_ptr<A>(/*ук-ль на объект A*/) выполнение new B ?
  • Вопрос задан
  • 1975 просмотров
Подписаться 3 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Похоже на ошибку оформления. Это должен быть вызов функции. В тексте выше даже написано про вызов.

Тут автор считает, что сначала выполнится new A(), потом new B(), потом конструктор unique_ptr. Если исключение бросит B(), то действительно будет утечка памяти. Объект A, полученный через new умрет еще до оборачивания в unique_ptr. Такой сырой указатель автоматически не удалится.

Такая последовательность невозможна c С++17:
In a function call, value computations and side effects of the initialization of every parameter are indeterminately sequenced with respect to value computations and side effects of any other parameter.


Evaluations of A and B are indeterminately sequenced : they may be performed in any order but may not overlap: either A will be complete before B, or B will be complete before A. The order may be the opposite the next time the same expression is evaluated.


Но до C++17, действительно, компилятор может перемешать вычисления аргументов как угодно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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