Получение повышения:: общий ptr для этого
Я широко использую boost:shared_ptr
в моем коде. Фактически, большинство объектов, которые выделяются в куче, удерживаются с помощью shared_ptr
. К сожалению, это означает, что я не могу пройти this
в любую функцию, которая принимает shared_ptr
. Рассмотрим этот код:
void bar(boost::shared_ptr<Foo> pFoo)
{
...
}
void Foo::someFunction()
{
bar(this);
}
здесь есть две проблемы. Во-первых, это не будет компилироваться, потому что конструктор T* для shared_ptr
явный. Во-вторых, если я заставлю его строить с bar(boost::shared_ptr<Foo>(this))
Я создал второй общий указатель на мой объект это в конечном итоге приведет к двойному удалению.
это подводит меня к моему вопросу: существует ли какой-либо стандартный шаблон для получения копии существующего общего указателя, который, как вы знаете, существует внутри метода на одном из этих объектов? Использует интрузивный подсчет ссылок мой единственный вариант здесь?
6 ответов:
можно получить из enable_shared_from_this и затем вы можете использовать "shared_from_this()" вместо "this", чтобы создать общий указатель на свой собственный объект.
пример ссылки:
#include <boost/enable_shared_from_this.hpp> class Y: public boost::enable_shared_from_this<Y> { public: shared_ptr<Y> f() { return shared_from_this(); } } int main() { shared_ptr<Y> p(new Y); shared_ptr<Y> q = p->f(); assert(p == q); assert(!(p < q || q < p)); // p and q must share ownership }
это хорошая идея при создании потоков из функции-члена для boost:: bind к shared_from_this() вместо этого. Это гарантирует, что объект не будет освобожден.
просто используйте необработанный указатель для параметра функции вместо shared_ptr. Цель интеллектуального указателя-управлять временем жизни объекта, но время жизни объекта уже гарантируется правилами области видимости C++: он будет существовать по крайней мере до конца вашей функции. То есть вызывающий код не может удалить объект до того, как ваша функция вернется; таким образом, безопасность" тупого " указателя гарантируется, Если вы не пытаетесь удалить объект внутри вашего функция.
единственный раз, когда вам нужно пройти shared_ptr в функцию, когда вы хотите передать право собственности на объект функции, или функции, чтобы сделать копию указателя.
boost имеет решение для этого случая использования, проверьте enable_shared_from_this
вы действительно делаете больше общих копий pFoo внутри бара? Если вы не делаете ничего сумасшедшего внутри, просто сделайте это:
void bar(Foo &foo) { // ... }
С C++11
shared_ptr
иenable_shared_from_this
Теперь в стандартной библиотеке. Последнее, как следует из названия, именно для этого случая.http://en.cppreference.com/w/cpp/memory/shared_ptr
http://en.cppreference.com/w/cpp/memory/enable_shared_from_this
пример базируется на этом в ссылках выше:
struct Good: std::enable_shared_from_this<Good>{ std::shared_ptr<Good> getptr() { return shared_from_this(); } };
использование:
std::shared_ptr<Good> gp1(new Good); std::shared_ptr<Good> gp2 = gp1->getptr(); std::cout << "gp2.use_count() = " << gp2.use_count() << '\n';
функция, принимающая указатель, хочет выполнить одно из двух действий:
- собственный объект В, и удалить его, когда он выходит из области видимости. В этом случае вы можете просто принять X* и сразу же обернуть scoped_ptr вокруг этого объекта (в теле функции). Это будет работать, чтобы принять " это " или, в общем случае, любой объект, выделенный для кучи.
- поделиться указатель (не владейте им) к передаваемому объекту. В этом случае вы делай не хотите использовать scoped_ptr, поскольку вы не хотите удалять объект в конце вашей функции. В этом случае то, что вы теоретически хотите, - это shared_ptr (я видел, что он называется linked_ptr в другом месте). Библиотека boost имеет версия shared_ptr, и это также рекомендуется в эффективной книге Скотта Мейерса на C++ (пункт 18 в 3-м издании).
Edit: Ой я немного неправильно понял вопрос, и теперь вижу этот ответ не совсем отвечает на вопрос. Я оставлю его в любом случае, в случае, если это может быть полезно для тех, кто работает над подобным кодом.