Oubliez les définitions
Ils vont polluer votre code.
bitfields ?
struct RecordFlag {
unsigned isnew:1, isdeleted:1, ismodified:1, isexisting:1;
};
N'utilise jamais ça. . Vous êtes plus préoccupé par la vitesse que par l'économie de 4 ints. L'utilisation de champs de bits est en fait plus lente que l'accès à tout autre type.
Cependant, les membres binaires dans les structs présentent des inconvénients pratiques. Tout d'abord, l'ordre des bits en mémoire varie d'un compilateur à l'autre. De plus, de nombreux compilateurs populaires génèrent un code inefficace pour la lecture et l'écriture des membres de bit et il existe des risques potentiellement graves les problèmes de sécurité des fils concernant les champs de bits (en particulier sur les systèmes multiprocesseurs) en raison du fait que la plupart des machines ne peuvent pas manipuler des ensembles arbitraires de bits en mémoire, mais doivent au contraire charger et stocker des mots entiers. Par exemple, l'exemple suivant ne serait pas thread-safe, malgré l'utilisation d'un mutex
Source : http://en.wikipedia.org/wiki/Bit_field :
Et si vous avez besoin de plus de raisons pour pas utiliser des champs de bits, peut-être Raymond Chen vous convaincra dans son L'ancien et le nouveau truc Poste : L'analyse coût-bénéfice des champs de bits pour une collection de booléens sur http://blogs.msdn.com/oldnewthing/archive/2008/11/26/9143050.aspx
const int ?
namespace RecordType {
static const uint8 xNew = 1;
static const uint8 xDeleted = 2;
static const uint8 xModified = 4;
static const uint8 xExisting = 8;
}
Les mettre dans un espace de nom est cool. S'ils sont déclarés dans votre CPP ou votre fichier d'en-tête, leurs valeurs seront inlined. Vous pourrez utiliser switch sur ces valeurs, mais cela augmentera légèrement le couplage.
Ah, oui : supprimer le mot-clé statique . static est déprécié en C++ lorsqu'il est utilisé comme vous le faites, et si uint8 est un type buildin, vous n'aurez pas besoin de le déclarer dans un en-tête inclus par plusieurs sources du même module. Au final, le code devrait être :
namespace RecordType {
const uint8 xNew = 1;
const uint8 xDeleted = 2;
const uint8 xModified = 4;
const uint8 xExisting = 8;
}
Le problème de cette approche est que votre code connaît la valeur de vos constantes, ce qui augmente légèrement le couplage.
enum
La même chose que const int, avec un typage un peu plus fort.
typedef enum { xNew = 1, xDeleted, xModified = 4, xExisting = 8 } RecordType;
Ils continuent cependant à polluer l'espace de noms global. D'ailleurs... Supprimez le typedef . Vous travaillez en C++. Ces typedefs d'enums et de structs polluent le code plus qu'autre chose.
Le résultat est sympathique :
enum RecordType { xNew = 1, xDeleted, xModified = 4, xExisting = 8 } ;
void doSomething(RecordType p_eMyEnum)
{
if(p_eMyEnum == xNew)
{
// etc.
}
}
Comme vous le voyez, votre enum pollue l'espace de nom global. Si vous mettez cet enum dans un espace de nom, vous aurez quelque chose comme :
namespace RecordType {
enum Value { xNew = 1, xDeleted, xModified = 4, xExisting = 8 } ;
}
void doSomething(RecordType::Value p_eMyEnum)
{
if(p_eMyEnum == RecordType::xNew)
{
// etc.
}
}
extern const int ?
Si vous voulez réduire le couplage (c'est-à-dire être capable de cacher les valeurs des constantes, et donc de les modifier à volonté sans avoir besoin d'une recompilation complète), vous pouvez déclarer les ints comme extern dans l'en-tête, et comme constantes dans le fichier CPP, comme dans l'exemple suivant :
// Header.hpp
namespace RecordType {
extern const uint8 xNew ;
extern const uint8 xDeleted ;
extern const uint8 xModified ;
extern const uint8 xExisting ;
}
Et :
// Source.hpp
namespace RecordType {
const uint8 xNew = 1;
const uint8 xDeleted = 2;
const uint8 xModified = 4;
const uint8 xExisting = 8;
}
Vous ne pourrez pas utiliser switch sur ces constantes, cependant. Donc, en fin de compte, choisissez votre poison... :-p