c ++: std :: tr1 :: shared_ptr из этого - PullRequest
0 голосов
/ 21 ноября 2011

У меня есть следующий код:

#include <memory>

class Foo;
typedef std::tr1::shared_ptr<Foo> pFoo_t;

class DoSomething
{
public:
    static void doSomething( pFoo_t p) { printf( "doing something...\n"); }
    static void doSomethingElse( pFoo_t p) { printf( "doing something else...\n"); }
};

class Foo
{
public:
    Foo() { printf( "foo()\n"); }
    ~Foo() { printf( "~foo()\n"); }
public:
    void doSomething() { DoSomething::doSomething(pFoo_t(this)); }
    void doSomethingElse() { DoSomething::doSomethingElse(pFoo_t(this)); }
};

int _tmain(int argc, _TCHAR* argv[])
{
    Foo foo;
    foo.doSomething();
    foo.doSomethingElse();

    return 0;
}

Я запускаю этот пример и получаю следующее утверждение: _BLOCK_TYPE_IS_VALID (pHead-> nBloakUse).

Как мне этого избежать?

Я использовал следующий код для решения этой проблемы:

class Foo;
typedef std::tr1::shared_ptr<Foo> pFoo_t;

class DoSomething
{
public:
    static void doSomething( pFoo_t p) { printf( "doing something...\n"); }
    static void doSomethingElse( pFoo_t p) { printf( "doing something else...\n"); }
};

class Foo
{
public:
    void Init(pFoo_t _pFoo) { m_pFoo = _pFoo; }
    Foo() { printf( "foo()\n"); }
    ~Foo() { printf( "~foo()\n"); }
public:
    void doSomething() { DoSomething::doSomething(m_pFoo.lock()); }
    void doSomethingElse() { DoSomething::doSomethingElse(m_pFoo.lock()); }
private:
    std::tr1::weak_ptr<Foo> m_pFoo;
};

int _tmain(int argc, _TCHAR* argv[])
{
    {
        Foo * foo = new Foo();
        pFoo_t pFoo(foo);
        foo->Init(pFoo);
        foo->doSomething();
        foo->doSomethingElse();
    }
    return 0;
}

Но я думаю, что есть лучшее решение.

Ответы [ 2 ]

6 голосов
/ 21 ноября 2011

Не используйте это вручную.Сделайте так, чтобы ваш класс наследовал от std::enable_shared_from_this и используйте std::shared_from_this() для получения общего указателя.

Кроме того, вы должны разместить свой объект прямо в общем указателе:

pFoo_t pFoo = std::make_shared<Foo>();  // good
pFoo_t pFoo(new Foo());                 // legacy

(Кстати, вы либо включаете <memory> для этого, либо используете версии TR1 всего этого (тогда нет make_shared) и включаете <tr1/memory>. Я знаю, что MSVC позволяет вам избежать неприятностей,но ради переносимости вы должны выбрать один или другой.)

0 голосов
/ 22 ноября 2011

Спасибо за ваш ответ.

Вы были правы.

Правильный код теперь выглядит следующим образом:

class Foo;
typedef std::tr1::shared_ptr<Foo> pFoo_t;

class DoSomething
{
public:
    static void doSomething( pFoo_t p) { printf( "doing something...\n"); }
    static void doSomethingElse( pFoo_t p) { printf( "doing something else...\n"); }
};

class Foo : public std::enable_shared_from_this<Foo> 
{
public:
    Foo() { printf( "foo()\n"); }
    ~Foo() { printf( "~foo()\n"); }
public:
    void doSomething() { DoSomething::doSomething(this->shared_from_this()); }
    void doSomethingElse() { DoSomething::doSomethingElse(this->shared_from_this()); }
};

int _tmain(int argc, _TCHAR* argv[])
{
    {
        auto pFoo = std::make_shared<Foo>();
        pFoo->doSomething();
        pFoo->doSomethingElse();
    }
    return 0;
}
...