引用计数类的库实现

时间:2018-09-03 08:08:13

标签: c++ boost std reference-counting

我有一个像这样的班级:

Texture
{
    int ID
public:
    Texture(std::string name){ ID = make_texture(name); }
    ~Texture(){ delete_texture(ID); }
};

但是问题是当我移动类时,析构函数会被调用,因此ID现在无效。

我当前的实现方式如下:

Texture
{
    static std::unordered_map<int> m;
    int ID
public:
    Texture(std::string name){
        ID = make_texture(name);
        m[ID]++;
    }
    Texture(Texture& obj){ *this = obj; }
    Texture &operator=(Texture& obj){
        ID = obj.ID;
        m[ID]++;
    }
    ~Texture(){
        if (!--m[ID])
            delete_texture(ID);
    }
};
//was coded in stack overflow so syntax may be a bit off

但是真正好的是一个我可以从中继承的类,

Texture : public ref_count<int>
{
    int ID
public:
    Texture(std::string name){ ID = make_texture(name); }
    key(){return ID;} // inherited from ref_count
    on_delete(){ delete_texture(ID); } // inherited from ref_count
};

所以我的问题是:标准/ boost库中是否存在这样的便捷类?还是在不实现自己的引用计数的情况下实现此目标的最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

扩大我的评论。您需要Texture个对象才能共享对同一ID的引用,因此,ID需要使用某种引用计数类型进行包装,以容纳Texture。这正是std::shared_ptr的用例。您所需要做的就是custom deleter,它将delete_texture作为释放托管整数的一部分。

class Texture
{
    std::shared_ptr<int> ID;
public:
    Texture(std::string name) :
      ID{ new int(make_texture(name)),
          [](int* id_ptr) {
            delete_texture(*id_ptr);
            delete id_ptr;
          }
        }
    {}
};

就是这样。 Texture的复制/移动/变形现在可以由编译器隐式生成,因为它依赖于std::shared_ptr的正确行为。