Подтвердить что ты не робот

Почему у boost нет make_scoped()?

Boost make_shared() функция promises должна быть исключающей безопасность при попытке создать shared_ptr.

Почему нет эквивалента make_scoped()? Есть ли общая передовая практика?

Вот пример кода из boost::scoped_ptr документации, который кажется мне небезопасным:

    boost::scoped_ptr<Shoe> x(new Shoe);

Эта строка кода сделает эти три вещи в порядке:

  • Выделить память кучи для Shoe
  • Вызов конструктора для Shoe
  • Вызов конструктора для boost::scoped_ptr<Shoe>

Если конструктор для Shoe выдает исключение, будет потеряна память . (см. R. Martinho Fernandes). scoped_ptr не будет обрабатывать освобождение, потому что он не был построено еще.

Это надзор? Или есть решение, которое я не заметил?

4b9b3361

Ответ 1

Если конструктор выходит из строя, утечка памяти не происходит. Эта часть семантики new, никаких интеллектуальных указателей:

struct Foo { Foo() { throw 23; } };
new Foo(); // no memory leaked

Добавленная безопасность исключений, предоставляемая make_shared, возникает, когда вы инициализируете два shared_ptr в выражении, а две инициализации не секвенированы, как это имеет место в аргументах вызова функции:

struct Bar {
    Bar(bool fail) {
        if(fail) throw 17;
    }
}
f(shared_ptr<Bar>(new Bar(true)), shared_ptr<Bar>(new Bar(false)));

Так как не существует последовательности между оценками new Bar(true), shared_ptr<Bar>(new Bar(true)), new Bar(false) и shared_ptr<Bar>(new Bar(false)), может случиться следующее:

  • new Bar(false) оценивается и преуспевает: выделена память;
  • new Bar(true) оценивается и терпит неудачу: он не утечки памяти в результате этой оценки;

В это время не было построено shared_ptr, и поэтому память, выделенная в # 1, теперь просочилась.

Ответ 2

scoped_ptr предшествует перемещению семантики и не поддается обработке по дизайну. Таким образом, make_scoped было бы невозможно реализовать, потому что для возврата объекта из функции его тип должен быть подвижным или скопированным.

Ответ 3

Если Shoe бросает, то Чистка не построена, поэтому ничего не может сделать scoped_ptr. Нет? Scoped_ptr x находится в стеке и будет очищен при выходе из области.