2009-12-18 16 views

Antwort

4

Anzahl der Objekte für das, was? Wenn Sie die Anzahl der Objekte einer bestimmten Klasse zählen möchten, können Sie einen statischen Zähler verwenden. So etwas wie unten .. Zähle bei der Erstellung und Abnahme während Zerstörung ..

class A 
{ 
    public: 
    static int counter; 
    A() 
    { 
     counter ++; 
    } 
    virtual ~A() 
    { 
     counter --; 
    } 
}; 

int A :: counter = 0; 
+0

Wie behalten Sie den Überblick, wenn das Objekt mit malloc erstellt wird? –

+0

@KranthiKumar Es * wird nicht * 'erstellt von 'malloc()'.' Es wird * statisch oder durch 'neu' oder auf dem Stapel zugewiesen; es ist * konstruiert * von einem seiner Konstruktoren; und es wird von seinem Destruktor zerstört. – EJP

0

Sie könnten eine Zählvariable in der Öffentlichkeit schaffen: Ihrer Klasse (vorausgesetzt, hier Sie sprechen über Objekte aus einer Klasse zählen Sie erstellt

)
class Widget { 
public: 
    Widget() { ++count; } 
    Widget(const Widget&) { ++count; } 
    ~Widget() { --count; } 

    static size_t howMany() 
    { return count; } 

private: 
    static size_t count; 
}; 
// obligatory definition of count. This 
// goes in an implementation file 
size_t Widget::count = 0; 

Entnommen ddj.com

+0

sollten Sie den ganzen Artikel von scott meyers lesen, um zu sehen, dass diese Lösung nicht die beste ist. Am Ende des Artikels beschreibt er den Template-Ansatz, der in den anderen Posts erwähnt wird. –

27

Template-Klasse mit einem statischen Zählern erstellen.

Jedes Objekt in Ihrer Anwendung würde dann diese Vorlagenklasse erweitern.

Wenn Konstruktor inkrementierte statische Anzahl aufgerufen wird (statische Variable ist pro Klasse - für alle Objekte dieser Klasse gemeinsam).

Zum Beispiel siehe Objektzähler mit Curiously recurring template pattern:

template <typename T> 
struct counter 
{ 
    counter() 
    { 
     objects_created++; 
     objects_alive++; 
    } 

    virtual ~counter() 
    { 
     --objects_alive; 
    } 
    static int objects_created; 
    static int objects_alive; 
}; 
template <typename T> int counter<T>::objects_created(0); 
template <typename T> int counter<T>::objects_alive(0); 

class X : counter<X> 
{ 
    // ... 
}; 

class Y : counter<Y> 
{ 
    // ... 
}; 

Verwendung der Vollständigkeit halber:

int main() 
{ 
    X x1; 

    { 
     X x2; 
     X x3; 
     X x4; 
     X x5; 
     Y y1; 
     Y y2; 
    } // objects gone 

    Y y3; 

    cout << "created: " 
     << " X:" << counter<X>::object_created 
     << " Y:" << counter<Y>::object_created 
     << endl; 

    cout << "alive: " 
     << " X:" << counter<X>::object_alive 
     << " Y:" << counter<Y>::object_alive 
     << endl; 
} 

Ausgang:

created: X:5 Y:3 
alive: X:1 Y:1 
+0

Hallo. Netter Ansatz. Ich wusste nie davon. Vielen Dank! – bdhar

+0

Vor einiger Zeit habe ich einen statischen Polymorphismus gemacht und bin auf dieses Beispiel gestoßen, ich mag es wirklich, und statische Polymorphie ist auch cool ... – stefanB

+0

Schöne Lösung, ich habe allerdings Zweifel ... ist es wirklich notwendig, den Destruktor zu machen virtuell in der Klassenvorlage bei Verwendung von CRTP? Ich mache mir nur Sorgen wegen der geringen Größe Overhead verursacht durch die V-Tabellen. – Naveen

10
template <class T> 
class Counter 
{ 
    private: 
     static int count; 
    public: 
    Counter() 
    { 
     count++; 
    } 
    Counter(const Counter &c) 
    { 
     count++; 
    } 
    ~Counter() 
    { 
     count--; 
    }  
    static int GetCount() { 

     return count; 
    } 
} 

template<class T> 
int Counter<T>::count = 0; 



class MyClass : private Counter<MyClass> 
{ 
    public: 
     using Counter<MyClass>::GetCount; 
} 

Diese Technikgenannt wird

+3

@stefanB, Dies ist der richtige Ansatz. Sie müssen einen Kopierkonstruktor in Counter haben. – Jagannath

+1

+1, der Ansatz von stefanB verarbeitet nicht 'X x2; X x3 = x2; '. Aber Sie können count nicht so initialisieren, da es nicht const ist. – KeatsPeeks

+0

du bist richtig ... ich hv, es zu definieren, Klasse. – Ashish

3

Sie müssen die neuen Operatoren überladen und löschen, um die Speicherzuweisungen zu zählen.

void * operator new (size_t size) 
{ 
    void * p = malloc (size); 
    num_allocations++; 
    return p; 
} 

void operator delete (void * p) 
{ 
    num_deletions++; 
    free (p); 
} 
+0

Ich denke, new [] und delete [] müssen auch überladen werden, wenn Sie Objekte auf Heap verfolgen möchten. – Ashish

+0

Ja, du bist richtig Mac. Ich habe nur versucht, ihn zu fangen. Sie müssen jede neue Variante, die Sie verwenden, überlasten. – DevDevDev

+0

stört das den Code nicht? delete sollte den Destruktor zuerst aufrufen; – NoSenseEtAl

Verwandte Themen