Если вас беспокоит то, что два выражения new Bar
, чередующиеся и выбрасываемые до инициализации дескрипторов для хранения того, что они означают, стандарт не позволяет этого.
Сначала в [intro .execution]
12 Полное выражение
- init-декларатор или mem-initializer, включая составляющие выражения инициализатора,
16 Каждое вычисление значения и побочный эффект, связанный с полным выражением, секвенируются перед каждым вычислением значения и побочным эффектом, связанным со следующим полным выражением, которое должно быть оценены.
Не вдаваясь в подробности, x{new Bar}
и y{new Bar}
в целом рассматриваются как то, что в стандарте считается "полным выражением" (даже если они не являются выражениями грамматически ). Два параграфа, которые я цитировал, указывают, что либо полная инициализация x
(которая включает в себя new Bar
) должна произойти первой, либо вся инициализация y
должна произойти первой. Мы знаем из [class.base.init]
13,3 - Затем элементы данных c, не относящиеся к состоянию, инициализируются в том порядке, в котором они были объявлено в определении класса (опять же, независимо от порядка инициализации mem).
Итак, x
инициализируется полностью, а затем y
. Таким образом, даже если new Bar
throws при инициализации y
, x
уже владеет ресурсом, который он должен хранить. В этом случае, когда выдается исключение, словосочетание в [exc.ctor] parageph 3 будет применяться к полностью построенному x
, и оно будет уничтожено, освобождая ресурс.