2009-12-18 17 views

Respuesta

4

Número de objetos para qué? Si desea contar el número de objetos de una clase específica, puede usar un contador estático. Algo parecido a continuación .. Incrementar contador de creación y destrucción de decremento mientras ..

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

int A :: counter = 0; 
+0

¿Cómo se hace un seguimiento si el objeto se crea con malloc? –

+0

@KranthiKumar It * no * * creado por 'malloc()'. ' Está * asignado * estáticamente, o por 'nuevo', o en la pila; es * construido * por uno de sus constructores; y es destruido por su destructor. – EJP

0

Se puede crear una variable de contador en el público: de la clase (suponiendo que aquí se está hablando de contar objetos de una clase que ha creado)

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; 

Tomado de ddj.com

+0

debe leer todo el artículo de scott meyers para ver que esta solución no es la mejor. Al final del artículo, describe el enfoque de plantilla mencionado en las otras publicaciones. –

27

Crear clase de plantilla con un contador estático.

Cada objeto en su aplicación extendería esta clase de plantilla.

Cuando al constructor se le llama conteo estático incremental (la variable estática es por clase - compartida por todos los objetos de esa clase).

Por ejemplo, véase objeto de contador utilizando 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> 
{ 
    // ... 
}; 

Uso para la integridad:

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; 
} 

de salida:

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

Hola. Buen enfoque. Nunca supe de eso. ¡Gracias! – bdhar

+0

Hace algún tiempo estaba haciendo un polimorfismo estático y me topé con este ejemplo, realmente me gusta, y el polimorfismo estático también es genial ... – stefanB

+0

Buena solución, aunque tengo una duda ... ¿es realmente necesario hacer el destructor? virtual en la plantilla de clase cuando se usa CRTP? Solo me preocupa el pequeño tamaño de sobrecarga causado por las tablas v. – 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; 
} 

Esta técnica se llama CRTP

+3

@stefanB, este es el enfoque correcto. Necesitas tener un constructor de copia en Counter. – Jagannath

+1

+1, el enfoque de stefanB no maneja 'X x2; X x3 = x2; '. Pero no puedes inicializar el conteo de esa manera, ya que no es const. – KeatsPeeks

+0

ya corriges ... quiero definirlo como clase de outsied. – Ashish

3

Tiene que sobrecargar el operador nuevo y eliminar para contar las asignaciones de memoria.

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

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

Creo que new [] y delete [] también tienen que estar sobrecargados si desea rastrear objetos en heap. – Ashish

+0

Sí, eres Mac correcto. Solo estaba tratando de hacerlo comenzar. Debe sobrecargar cada variación de nuevo que esté utilizando. – DevDevDev

+0

no rompe el código? delete debería llamar primero a destructor; – NoSenseEtAl

Cuestiones relacionadas