C ++设计问题(需要便宜的智能指针)

时间:2009-12-23 04:34:45

标签: c++ smart-pointers

我有一棵巨大的树,其中的键内部节点是一个大的hash_map v的索引, 其中v [key]是与该键相关联的(大)记录(包括树中有多少个节点具有此键)。现在,key是一个整数。所以每个节点 有存储子项指针和整数的开销 我们可以从树中的节点中删除密钥。 我们不能将实际记录存储在树节点中(因为那将是内存耗尽)。 从节点中删除密钥时,我们需要查看v,更新计数并删除元素 (并压缩矢量)。

这迫切需要一个智能指针实现:我们在树周围有一个shared_ptr传播。 一旦引用了密钥k的最后一个节点被删除,该对象就会被破坏。

但是,我对shared_ptr的大小要求持怀疑态度。我需要一个cheep参考计数 智能柜台。我不关心并发访问。

2 个答案:

答案 0 :(得分:2)

这是一个简单的引用计数智能指针,几年前我从网上摘取并修补了一点:

/// A simple non-intrusive reference-counted pointer.
/// Behaves like a normal pointer to T, providing 
/// operators * and ->. 
/// Multiple pointers can point to the same data
/// safely - allocated memory will be deleted when 
/// all pointers to the data go out of scope.
/// Suitable for STL containers.
///
template <typename T> class counted_ptr
{
public:
    explicit counted_ptr(T* p = 0)
        : ref(0)
    {
        if (p)
            ref = new ref_t(p);
    }

    ~counted_ptr()
    {
        delete_ref();
    }

    counted_ptr(const counted_ptr& other)
    {
        copy_ref(other.ref);
    }

    counted_ptr& operator=(const counted_ptr& other)
    {
        if (this != &other)
        {
            delete_ref();
            copy_ref(other.ref);
        }

        return *this;
    }

    T& operator*() const
    {
        return *(ref->p);
    }

    T* operator->() const
    {
        return ref->p;
    }

    T* get_ptr() const
    {
        return ref ? ref->p : 0;
    }

    template <typename To, typename From> 
    friend counted_ptr<To> up_cast(counted_ptr<From>& from);

private: // types & members

    struct ref_t
    {
        ref_t(T* p_ = 0, unsigned count_ = 1)
            : p(p_), count(count_)
        {
        }

        T* p;
        unsigned count;
    };

    ref_t* ref;

private: // methods

    void copy_ref(ref_t* ref_)
    {
        ref = ref_;

        if (ref)
            ref->count += 1;
    }

    void delete_ref()
    {
        if (ref)
        {
            ref->count -= 1;

            if (ref->count == 0)
            {
                delete ref->p;
                delete ref;
            }

            ref = 0;
        }
    }
};

每个智能指针的存储要求是适度的:只有真实指针和引用计数。

答案 1 :(得分:1)

为什么不扩展树实现以跟踪存储在其中的密钥的计数?您需要的只是另一个散列映射(或现有散列映射的每个记录中的附加字段)以跟踪计数,并在树的添加/删除函数中添加一些逻辑以适当地更新计数。