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

Может ли генерировать класс из "enable_shared_from_this" повысить производительность?

make_shared более эффективен, чем отдельный вызов new и создает shared_ptr, потому что make_shared выделяет пространство для подсчета ссылок и слабого подсчета в том же блоке памяти, что и экземпляр объекта клиента (эффективно давая shared_ptr большинство преимуществ производительности intrusive_ptr).

enable_shared_from_this дает общий указатель без ссылки на какой-либо общий указатель. Поэтому такие вещи, как ссылочный и слабый счет, должны быть как-то доступны изнутри клиентского объекта. Поэтому было бы разумно, чтобы enable_shared_from_this вызывал интрузивный счет, похожий на make_shared.

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

Будет ли смысл тогда (по соображениям производительности) отмечать мой класс enable_shared_from_this, если я знаю, что он когда-либо будет использоваться как shared_ptr и никогда не будет как необработанный объект?

4b9b3361

Ответ 1

Я никогда не врывался в детали реализации, но для shared_from_this для работы объект уже должен управляться внешним shared_ptr, поэтому он в какой-то мере не связан. То есть первый shared_ptr мог быть создан с помощью make_shared, и в этом случае счетчик и объект будут вместе (как вы говорите, назойливым указателем вроде), но это не обязательно.

Мое первое предположение состоит в том, что enable_shared_from_this добавляет эквивалент weak_ptr, а не a shared_ptr. EDIT: Я только что проверил реализацию в gcc4.6:

template <typename _Tp>
class enable_shared_from_this {
...
mutable weak_ptr<_Tp> _M_weak_this;
};

Ответ 2

Я так не верю. Реализация enable_shared_from_this не строго определена, но пример реализации присутствует в стандарте, который соответствует тому, как это делается. В основном, есть скрытый weak_ptr, который shared_ptr и друзья имеют доступ к... в любое время a shared_ptr предоставляется право собственности на объект, полученный из enable_shared_from_this, он обновляет внутренний указатель. Тогда shared_from_this() просто возвращает сильную версию этого слабого указателя.

В общем случае реализация не может предполагать, что никто никогда не перейдет shared_ptr(new T) вместо использования make_shared, поэтому назойливый счетчик ссылок будет рискован. Вы можете вместо этого сделать этот guarentee самостоятельно, любым способом, который вы используете для создания объектов в первую очередь.

Ответ 3

Boost enable_shared_from_this не меняет реализацию самого shared_ptr. Помните, что shared_ptr сопряжен с weak_ptr - это означает, что даже после удаления объекта данные отслеживания могут остаться вокруг, чтобы сообщить weak_ptr, что объект мертв. Таким образом, он не может быть встроен в объект, даже с enable_shared_from_this. Все enable_shared_from_this действительно вставляет указатель на данные отслеживания в объект, поэтому shared_ptr может быть сконструирован только с указателем на объект.

Вот почему intrusive_ptr не может иметь вариант weak_intrusive_ptr.