Может ли получение класса из 'enable_shared_from_this' повысить производительность? - PullRequest
18 голосов
/ 29 июня 2011

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, а не как необработанный объект?

Ответы [ 3 ]

8 голосов
/ 29 июня 2011

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

Мое первое предположение состоит в том, что enable_shared_from_this добавляет эквивалент weak_ptr, а не shared_ptr. РЕДАКТИРОВАТЬ : Я только что проверил реализацию в gcc4.6:

template <typename _Tp>
class enable_shared_from_this {
...
mutable weak_ptr<_Tp> _M_weak_this;
};
1 голос
/ 29 июня 2011

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

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

0 голосов
/ 29 июня 2011

Boost's 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.

...