2017-04-23 2 views
2

Ich versuche, eine eindeutige ID für jedes erstellte Objekt zu haben, während ich gleichzeitig nachverfolge, wie viele Instanzen des Objekts erstellt wurden. Aber wenn der Destruktor aufgerufen und der Zähler verringert wird, ändert sich die ID mit.Statischer Zähler - wie ID nicht geändert wird [C++]

.h

class Objekt 
    { 
    public: 
     Objekt(); 
    ~Objekt(); 

    int ID; 
    static int get_counter(); 

private: 
    static int counter; 

}; 

CPP

#include "Objekt.h" 



Objekt::Objekt() 
{ 
    counter++; 
    ID = counter; 
} 


Objekt::~Objekt() 
{ 
    --counter; 
} 

int Objekt::get_counter() 
{ 
    return counter; 
} 
+0

Können Sie ein [mcve] bereitstellen, das unerwartetes Verhalten zeigt? – aschepler

Antwort

1

Wenn Sie eine eindeutige ID wollen, müssen Sie zwei Zähler haben: (1) die Anzahl der Live-Objekte und (2) die Anzahl der Objekte erstellt [um die IDs zu erstellen].

Ihr System hier wird Objekte mit doppelten IDs erstellen.

+0

Das ist ein guter Punkt bei doppelten IDs, das Programm wird IDs nur korrekt anwenden, wenn kein Objekt zerstört wird, bevor ein anderes erstellt wird. –

+0

hat funktioniert! Danke! – 5arg

1

Entkoppeln Sie die Idee des Zählers von den IDs. In der Klasse:

static int currentID; 

Und nur den Konstruktor ändern:

Objekt::Objekt() 
{ 
    counter++; 
    currentID++; 
    ID = currentID; 
} 

Zähler wird nun die Anzahl der lebendig Objekte halten, während CurrentID die Anzahl aller halten Objekt, das jemals erstellt (auch gut für IDs erhalten).

0

Die Art, wie Sie es geschrieben haben ID ist eigentlich eine Objektinstanznummer, die schließlich wiederverwendet und durcheinander gebracht wird. Möglicherweise möchten Sie stattdessen einen nicht-abnehmenden, vernünftig großen (uint64) Zähler verwenden oder eine realistischere ID verwenden, die von ::boost::uuid for example generiert wird.

class Objekt 
{ 
    public: 
    Objekt(): m_id(::boost::uuids::random_generator()()) {} 

    public: 
    ~Objekt() {} 

    private: ::boost::uuids::uuid const m_id; 
}; 
0

, wenn der Destruktor aufgerufen wird und der Zähler verringert wird, damit die ID Änderungen.

Ich schlage vor, Sie verwenden zwei Zähler, Ctor und Dtor.

class Objekt 
{ 
public: 
    Objekt() 
    { 
     ctorCount++; 
     ID = ctorCount; 
    } 

    ~Objekt 
    { 
     dtorCount++; 
    } 
    int activeInstances() { return (ctorCount - dtorCount); } 
    int maxInstanceId() { return (ctorCount); } 
    int staleInstances() { return (dtorCount); } 

private:  
    static int ctorCount; // accessible by all instances 
    static int dtorCount; 

}; 



int Objekt::ctorCount = 0; 
int Objekt::dtorCount = 0; 

Wenn eine Instanz entfernt wurde, wird die ID nicht geändert und die nächste ID ist immer eindeutig.

Beachten Sie, dass Lücken zwischen IDs auftreten können. Die Zahl activeInstances() ist korrekt, berechnet aber nicht eine bestimmte ID, noch das max (auf das maxInstanceId() zugreifen kann).