c ++ tr1 enable_shared_from_this в чем преимущество? - PullRequest
0 голосов
/ 18 ноября 2011

Я сейчас читаю через расширения C ++ TR1 и начал фокусироваться на std :: tr1 :: shared_ptr.

Итак, я прочитал, что могу объявить и инициализировать shared_ptr <> с помощью этого кода:

class foo {};
std::tr1::shared_ptr<foo> fsp(new foo);
std::tr1::shared_ptr<foo> fps2(fsp);    // (1) init using first sp

Теперь я читаю о enable_shared_from_this (http://msdn.microsoft.com/en-us/library/bb982611%28v=VS.90%29.aspx) и вижу этот пример:

class foo : public enable_shared_from_this<foo> {};
std::tr1::shared_ptr<foo> fsp(new foo);
std::tr1::shared_ptr<foo> fps2 = fsp->shared_from_this(); // (2) init using first sp

Мой вопрос: почему я хотел бы использовать shared_from_this по сравнению с инициализацией?Я пометил как «(1) init используя first sp».

Я прочитал статью В чем полезность `enable_shared_from_this`? и теперь лучше понимаю ее полезность.

Но это оставляет меня открытым, в порядке ли мой "(1) init, использующий first sp", или с какими минусами я мог столкнуться, используя его.

Ответы [ 2 ]

3 голосов
/ 18 ноября 2011

enable_shared_from_this наиболее полезен в реализации класса, чьи объекты будут совместно использоваться.Вы хотите использовать один и тот же счетчик ссылок для всех экземпляров shared_ptr вашего объекта (обычно это делается путем копирования shared_ptr), но реализация класса не должна создавать копию.В этом случае вы можете использовать shared_from_this.

Рассмотрим:

struct A;

void f(shared_ptr<A> const&) {...}

struct A: public enable_shared_from_this<A>
{
    void a_f()
    {
        // you need to call f() here passing itself as a parameter
        f(shared_from_this());
    }
};

shared_ptr<A> a_ptr(new A());
a_ptr->a_f(); // in inner call to f() will be used temporary shared_ptr<A> 
// that uses (shares) the same reference counter as a_ptr 
1 голос
/ 18 ноября 2011

AFAIK ваше заявление (1) в порядке.enable_shared_from_this означает получение shared_ptr от объекта, если у вас уже есть shared_ptr, вам не нужно его вызывать.

...