2012-06-04 21 views
6

Estoy tratando de crear una clase Data cuyos objetos tienen cada uno un ID único.contador estático en C++

quiero Identificación del primero de objeto a ser 1, el segundo a ser 2, etc. Debo utilizar un static int, pero todos los objetos tienen el mismo ID, no 1, 2, 3 ...

Esta es la clase Data:

class Data 
{ 
private: 
    static int ID; 
public: 
    Data(){ 
    ID++; 
    } 
}; 

¿Cómo puedo hacer que lo que el primero de ellos sería ID 1, la segunda sería 2, etc ..?

+0

Asegúrese de que t Tenga cuidado con el multihilo, ya que la variable es 'estática'. – iammilind

+0

Generalmente las personas usan 'long' para esto en lugar de' int'. – shan

+0

@shan: ¿Qué personas? Puede ser lo que él quiera. –

Respuesta

9

Si el ID es estático, tendrá el mismo valor para todas las instancias de clase.

Si desea que cada instancia de tener valores de ID secuenciales, entonces se podría combinar el atributo estático con una variable de clase, así:

class Data 
{ 
private: 
    static int ID; 
    int thisId; 
public: 
    Data(){ 
    thisId = ++ID; 
    } 
}; 

int Data::ID = 0; 

Si la aplicación va a ser multi roscado, entonces tendrá para sincronizarlo con algo así como pthread mutex.

+0

gracias, pensé en esta solución, pero me preguntaba si hay otra forma de hacerlo, solo con la int estática, ya que se me solicitó que lo hiciera usando static int solamente. ¡Gracias! :) – Jjang

+0

@Jjang, puedes hacerlo con solo una int estática si solo imprimes el valor en el constructor, pero si necesitas *** almacenar *** el valor secuencial único, entonces necesitarás algo más que solo la estática int. – Brady

+0

@Jjang: No puede tener * id * únicos por objeto con una sola identificación * shared * ('static'), eso no tiene ningún sentido. –

14

Este:

class Data 
{ 
private: 
    static int ID; 
    const int currentID; 
public: 
    Data() : currentID(ID++){ 
    } 
}; 

Además de un contador estático, también necesita un miembro de instancia de ruedas.

+3

La identificación del miembro debe ser un campo 'const'. Una vez que se crea el objeto, probablemente tiene poco sentido cambiarlo. También inhibirá automáticamente que 'operator = 'sobrescriba el ID del objeto, aunque el usuario se quede con la responsabilidad de proporcionar un constructor de copia que no reutilice el ID del objeto fuente. –

+0

@ DavidRodríguez-dribeas buen punto. –

+0

Hago clic en un error al usar 'const' debido quizás a mi constructor de copia declarado por el usuario. Ver [esta respuesta] (http://stackoverflow.com/a/37517125/5272567). Al eliminar 'const'" se solucionó "esto, por supuesto, eso significa que la variable no es' const'. – Matthias

1

Cada instancia de Data necesita su propia variable miembro no estática que almacena su ID. Una variable static se puede usar para almacenar la última ID usada que se incrementaría en el constructor de Data.

En lugar de un contador de static, que no es seguro para subprocesos, considere el uso boost's uuid:

#include <boost/lexical_cast.hpp> 
#include <boost/uuid/uuid.hpp> 
#include <boost/uuid/uuid_generators.hpp> 
#include <boost/uuid/uuid_io.hpp> 

using boost::lexical_cast; 
using boost::uuids::uuid; 
using boost::uuids::random_generator; 

std::string id_ = lexical_cast<std::string>((random_generator())()); 
-1

donde es el identificador (no estático) aquí instancia? tiene que declarar un nuevo campo de identificador de instancia como esta

int m_ID; 

entonces en su constructor hacer

Data(){m_ID = ::InterlockedIncrement(&ID);} 

de una manera segura para los subprocesos interlocked u otro

+0

Buena idea, pero ¿qué tan portátil es eso? – Brady

+1

No es portátil en absoluto, por supuesto ;-) Solo estaba dando un ejemplo. – Bond

1

inicialización de la variable estática dentro de una función está permitido por lo que una solución puede ser algo como esto

class Data 
{ 
    private: 
    static int ID() 
    { 
     static int ID = 0; 
     return ID ++; 
    } 
    int myId; 

    public: 
    Data(): myId (ID()) 
    {  
    } 
};