[ create a new paste ] login | about

Link: http://codepad.org/rQiAg0yO    [ raw code | output | fork ]

C++, pasted on Jun 7:
#include <cassert>
#include "boost/shared_ptr.hpp"

struct Hoge;
struct HogeRegistry { void insert(Hoge*); void erase(Hoge*); };

struct WrappingDeleter
{
    HogeRegistry& owner;
    boost::shared_ptr<Hoge> original_holder;
    WrappingDeleter(HogeRegistry& owner, boost::shared_ptr<Hoge>& inserted)
        : owner(owner)
        , original_holder(inserted) {}
    void operator () (Hoge* raw)
    {
        assert(raw == original_holder.get());
        owner.erase(raw);
    }
};

void insert(HogeRegistry& hogeReg, boost::shared_ptr<Hoge>& hoge)
{
    Hoge* const raw = hoge.get();
    hogeReg.insert(hoge.get());
    try
    {
        boost::shared_ptr<Hoge> const wrapping(raw, WrappingDeleter(hogeReg, hoge));
        // wrapping (およびそのコピー)が生きている間はデリータが
        // 持っているオリジナルの shared_ptr が生き続ける。
        hoge = wrapping;
    }
    catch (...)
    {
        hogeReg.erase(hoge.get());
        throw;
    }
}

#include <iostream>
#include "boost/noncopyable.hpp"

#define LOG(p) (std::cout << __PRETTY_FUNCTION__ << ": " << static_cast<void const*>(p) << std::endl)
struct Hoge : boost::noncopyable
{
    Hoge()
    {
        LOG(this);
    }
    ~Hoge()
    {
        LOG(this);
    }
};
void HogeRegistry::insert(Hoge* p)
{
    LOG(p);
}
void HogeRegistry::erase(Hoge* p)
{
    LOG(p);
}

int main()
{
    HogeRegistry hogeReg;
    {
        std::cout << "Case NG." << std::endl;
        boost::shared_ptr<Hoge> hoge(new Hoge());
        hogeReg.insert(hoge.get());
    }
    {
        std::cout << "Case OK." << std::endl;
        boost::shared_ptr<Hoge> hoge(new Hoge());
        insert(hogeReg, hoge);
    }
    return 0;
}


Output:
1
2
3
4
5
6
7
8
9
Case NG.
Hoge::Hoge(): 0x8052248
void HogeRegistry::insert(Hoge*): 0x8052248
Hoge::~Hoge(): 0x8052248
Case OK.
Hoge::Hoge(): 0x8052248
void HogeRegistry::insert(Hoge*): 0x8052248
void HogeRegistry::erase(Hoge*): 0x8052248
Hoge::~Hoge(): 0x8052248


Create a new paste based on this one


Comments: