C++: Multi-threading-und Referenz-Zählung

Derzeit ive bekam einige Referenz gezählt Klassen mit den folgenden:

class RefCounted
{
public:
    void IncRef()
    {
        ++refCnt;
    }
    void DecRef()
    {
        if(!--refCnt)delete this;
    }
protected:
    RefCounted():refCnt(0){}
private:
    unsigned refCnt;
    //not implemented
    RefCounted(RefCounted&);
    RefCounted& operator = (RefCounted&};
};

Ich habe auch eine smart-pointer-Klasse, die Griffe Referenz zählen , obwohl seine nicht einheitlich verwendet (z.B. in ein oder zwei bits von performance-kritischen code, wo ich minimierte die Anzahl der IncRef und DecRef Anrufe).

template<class T>class RefCountedPtr
{
public:
    RefCountedPtr(T *p)
    :p(p)
    {
        if(p)p->IncRef();
    }
    ~RefCountedPtr()
    {
        if(p)p->DecRef();
    }
    RefCountedPtr<T>& operator = (T *newP)
    {
        if(newP)newP->IncRef();
        if(p)   p   ->DecRef();
        p = newP;
        return *this;
    }
    RefCountedPtr<T>& operator = (RefCountedPtr<T> &newP)
    {
        if(newP.p)newP.p->IncRef();
        if(p)     p     ->DecRef();
        p = newP.p;
        return *this;
    }
    T& operator *()
    {
        return *p;
    }
    T* operator ->()
    {
        return p;
    }
    //comparison operators etc and some const versions of the above...
private:
    T *p;
};

Für die Allgemeine Verwendung von den Klassen selbst ich planen, zu verwenden reader - /writer-locking-system, aber ich möchte wirklich nicht zu haben, um eine writer-Sperre für jeden einzelnen IncRef und DecRef nennen.

Ich auch nur daran gedacht, ein Szenario, in dem der Zeiger kann ungültig erklärt werden, kurz bevor die IncRef nennen, die Sie berücksichtigen sollten:

class Texture : public RefCounted
{
public:
    //...various operations...
private:
    Texture(const std::string &file)
    {
        //...load texture from file...
        TexPool.insert(this);
    }
    virtual ~Texture()
    {
        TexPool.erase(this);
    }
    freind CreateTextureFromFile;
};
Texture *CreateTexture(const std::string &file)
{
    TexPoolIterator i = TexPool.find(file);
    if(i != TexPool.end())return *i;
    else return new Texture(file);
}
ThreadA ThreadB 
t = CreateTexture("ball.png"); 
t->IncRef(); 
...Gebrauch t... t2 = CreateTexture("ball.png");//gibt *t 
... Faden aufgehängt... 
t->DecRef();//löscht t ... 
... t2->IncRef();//FEHLER 

So, ich glaube, ich muss zum ändern der ref zu zählen-Modell vollständig, der Grund, warum ich fügte hinzu, ein ref nach der Rückkehr in das design zu unterstützen Dinge wie die folgenden:

MyObj->GetSomething()->GetSomethingElse()->DoSomething();

statt:

SomeObject a = MyObj->GetSomething();
AnotherObject *b = a->GetSomethingElse();
b->DoSomething();
b->DecRef();
a->DecRef();

Gibt es eine saubere Möglichkeit für die schnelle reference counting in c++ in einer multi-threaded Umgebung?

InformationsquelleAutor Fire Lancer | 2009-07-16
Schreibe einen Kommentar