0

次のコードがあります。

#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;
}

しかし、もっと良い解決策があると思います。

4

2 に答える 2

6

これを手動で実装しないでください。クラスを継承させ、共有ポインターを取得するためにstd::enable_shared_from_this使用します。std::shared_from_this()

さらに、オブジェクトを共有ポインターに割り当てる必要があります。

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

(ちなみに、<memory>これには include を使用するか、このすべての TR1 バージョンを使用し (その場合は はありませんmake_shared)、 include<tr1/memory>を使用します。MSVC を使用すると、多くのだらしない作業を回避できることはわかっていますが、移植性のために選択する必要があります。どちらか一方。)

于 2011-11-21T14:37:55.197 に答える
0

お返事をありがとうございます。

君は正しかった。

正しいコードは次のようになりました。

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;
}
于 2011-11-22T06:23:49.563 に答える