Да, ваш новый код в порядке.Тем не менее, обратите внимание, что в более сложных случаях возможна небольшая вероятность:
#include <memory>
struct foo {
foo(std::shared_ptr<int> a, std::shared_ptr<int> b) { }
};
struct bar {
foo f;
bar() : f(std::shared_ptr<int>(new int), std::shared_ptr<int>(new int)) { }
};
int main() {
bar b;
}
не будет безопасным, однако, поскольку порядок вычисления аргументов конструктора foo
в списке инициализаторов bar
не указаноСоответствующий компилятор может предпочесть выполнить глубину или ширину первого порядка оценки (или что-нибудь еще, если они все были правильно оценены в конце).Это означает, что если первый new int
завершился успешно, но второй бросил до того, как объекты shared_ptr
были сконструированы, то первое выделение, которое должно быть выполнено, может все еще утечь.
Если вы обнаружите, что хотите это сделать, естьдва возможных решения, помимо простого возврата к двухфазному построению: первое могло бы быть рефакторингом, второе состояло бы в том, чтобы создать shared_ptr
индивидуально сначала как элементы bar, до f
.Что из этого является наиболее подходящим - это решение, которое, по моему мнению, необходимо делать в каждом конкретном случае.