当没有更多引用时,如何从缓存中删除智能指针? [英] How to remove smart pointers from a cache when there are no more references?

查看:79
本文介绍了当没有更多引用时,如何从缓存中删除智能指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试使用智能指针来升级现有的应用程序,我试图克服一个谜题。在我的应用程序中,我有一个对象缓存,例如让他们叫他们的书。现在,这个图书缓存由ID请求,如果它们在缓存中,则它们被返回,如果不是,则从外部系统请求对象(缓慢操作)并将其添加到缓存。一旦在缓存中许多窗口可以在应用程序中打开,这些窗口中的每一个都可以参考这本书。在先前版本的应用程序中,程序员必须维护AddRef和Release,当使用Book对象的每个窗口关闭时,最终的Release(在缓存管理器上)将从缓存中删除对象并删除对象。

I've been trying to use smart pointers to upgrade an existing app, and I'm trying to overcome a puzzle. In my app I have a cache of objects, for example lets call them books. Now this cache of books are requested by ID and if they're in the cache they are returned, if not the object is requested from an external system (slow operation) and added to the cache. Once in the cache many windows can be opened in the app, each of these windows can take a reference to the book. In the previous version of the app the programmer had to maintain AddRef and Release, when every window using the Book object was closed, the final Release (on the cache manager) would remove the object from the cache and delete the object.

您可能在这里发现了链接中的弱链接,这当然是程序员记得调用AddRef和Release。现在我已经移动到智能指针(boost :: intrusive)我不再担心调用AddRef和Release。然而,这导致一个问题,缓存有对对象的引用,因此当最后的窗口关闭时,缓存没有通知没有其他人持有引用。

You may have spotted the weak link in the chain here, it is of course the programmer remembering to call AddRef and Release. Now I have moved to smart pointers (boost::intrusive) I no longer have to worry about calling AddRef and Release. However this leads to a problem, the cache has a reference to the object, so when the final window is closed, the cache is not notified that no-one else is holding a reference.

我的第一个想法是定期地使用引用计数为1的缓存和清除对象。我不喜欢这个想法,因为它是一个秩序N操作,不觉得正确。我想出了一个回调系统,这是更好,但不奇妙。我已经包括回调系统的代码,但我想知道是否有人有更好的方法这样做。

My first thoughts were to periodically walk the cache and purge objects with a reference count of one. I didn't like this idea, as it was an Order N operation and didn't feel right. I have come up with a callback system, which is better but not fantastic. I have included the code for the callback system, however I was wondering if anyone had a better way of doing this?

class IContainer
{
public:
    virtual void FinalReference(BaseObject *in_obj)=0;
};

class BaseObject 
{
    unsigned int m_ref;

public:
    IContainer *m_container;

    BaseObject() : m_ref(0),m_container(0)
    {
    }

    void AddRef()
    {
        ++m_ref;
    }
    void Release()
    {
        // if we only have one reference left and we have a container
        if( 2 == m_ref && 0 != m_container )
        {
            m_container->FinalReference(this);
        }

        if( 0 == (--m_ref) )
        {
            delete this;
        }
    }
};

class Book : public BaseObject
{
    char *m_name;
public:
    Book()
    {
        m_name = new char[30];
        sprintf_s(m_name,30,"%07d",rand());
    }
    ~Book()
    {
        cout << "Deleting book : " << m_name;
        delete [] m_name;
    }

    const char *Name()
    {
        return m_name;
    }
};

class BookList : public IContainer
{
public:
    set<BookIPtr> m_books;

    void FinalReference(BaseObject *in_obj)
    {
        set<BookIPtr>::iterator it = m_books.find(BookIPtr((Book*)in_obj));
        if( it != m_books.end() )
        {
            in_obj->m_container = 0;
            m_books.erase( it );
        }
    }
};

namespace boost
{
    inline void intrusive_ptr_add_ref(BaseObject *p)
    {
        // increment reference count of object *p
        p->AddRef();
    }
    inline void intrusive_ptr_release(BaseObject *p)
    {
        // decrement reference count, and delete object when reference count reaches 0
        p->Release();
    } 
} // namespace boost

干杯
Rich

Cheers Rich

推荐答案

我从来没有使用过boost :: intrusive智能指针,但如果你使用shared_ptr智能指针,你可以使用weak_ptr对象缓存。

I never used boost::intrusive smart pointers, but if you would use shared_ptr smart pointers, you could use weak_ptr objects for your cache.

当系统决定释放内存时,这些weak_ptr指针不会作为引用计数,但只要对象不存在,就可以使用它来检索shared_ptr已被删除。

Those weak_ptr pointers do not count as a reference when the system decides to free their memory, but can be used to retrieve a shared_ptr as long as the object has not been deleted yet.

这篇关于当没有更多引用时,如何从缓存中删除智能指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆