Vergessen Sie die Definitionen
Sie werden Ihren Code verschmutzen.
bitfields?
struct RecordFlag {
unsigned isnew:1, isdeleted:1, ismodified:1, isexisting:1;
};
Benutzen Sie das niemals . Es geht Ihnen mehr um die Geschwindigkeit als um die Einsparung von 4 Ints. Die Verwendung von Bit-Feldern ist tatsächlich langsamer als der Zugriff auf jeden anderen Typ.
Bit-Members in Structs haben jedoch praktische Nachteile. Erstens variiert die Anordnung der Bits im Speicher von Compiler zu Compiler. Darüber hinaus, viele gängige Compiler erzeugen ineffizienten Code für das Lesen und Schreiben von Bitelementen und es gibt potenziell schwerwiegende Fragen der Gewindesicherheit in Bezug auf Bit-Felder (insbesondere auf Multiprozessorsystemen), da die meisten Maschinen nicht beliebige Bit-Sätze im Speicher manipulieren können, sondern stattdessen ganze Wörter laden und speichern müssen. z.B. wäre das Folgende trotz der Verwendung eines Mutex nicht thread-sicher
Quelle: http://en.wikipedia.org/wiki/Bit_field :
Und wenn Sie noch mehr Gründe brauchen, um no Bitfelder verwenden, vielleicht Raymond Chen wird Sie in seinem Die alte neue Sache Beitrag: Die Kosten-Nutzen-Analyse von Bitfeldern für eine Sammlung von Booleschen Werten unter 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;
}
Sie in einen Namensraum zu packen ist cool. Wenn sie in Ihrer CPP- oder Header-Datei deklariert sind, werden ihre Werte inlined. Sie werden in der Lage sein, switch auf diese Werte zu verwenden, aber es wird die Kopplung leicht erhöhen.
Ah, ja: das Schlüsselwort static entfernen . static ist in C++ veraltet, wenn es so verwendet wird, wie Sie es tun, und wenn uint8 ein Buildin-Typ ist, brauchen Sie dies nicht in einem Header zu deklarieren, der von mehreren Quellen desselben Moduls eingebunden wird. Am Ende sollte der Code so aussehen:
namespace RecordType {
const uint8 xNew = 1;
const uint8 xDeleted = 2;
const uint8 xModified = 4;
const uint8 xExisting = 8;
}
Das Problem bei diesem Ansatz ist, dass Ihr Code den Wert Ihrer Konstanten kennt, was die Kopplung leicht erhöht.
enum
Dasselbe wie const int, mit einer etwas stärkeren Typisierung.
typedef enum { xNew = 1, xDeleted, xModified = 4, xExisting = 8 } RecordType;
Sie verschmutzen aber immer noch den globalen Namensraum. Übrigens... Entfernen Sie den Typedef . Sie arbeiten in C++. Diese Typedefs von Enums und Structs verschmutzen den Code mehr als alles andere.
Das Ergebnis ist irgendwie:
enum RecordType { xNew = 1, xDeleted, xModified = 4, xExisting = 8 } ;
void doSomething(RecordType p_eMyEnum)
{
if(p_eMyEnum == xNew)
{
// etc.
}
}
Wie Sie sehen, verschmutzt Ihre Enum den globalen Namespace. Wenn Sie diese Aufzählung in einen Namespace stellen, haben Sie etwas wie:
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 ?
Wenn Sie die Kopplung verringern wollen (d.h. die Werte der Konstanten ausblenden und so nach Belieben ändern können, ohne dass eine vollständige Neukompilierung erforderlich ist), können Sie die ints als extern im Header und als Konstante in der CPP-Datei deklarieren, wie im folgenden Beispiel:
// Header.hpp
namespace RecordType {
extern const uint8 xNew ;
extern const uint8 xDeleted ;
extern const uint8 xModified ;
extern const uint8 xExisting ;
}
Und:
// Source.hpp
namespace RecordType {
const uint8 xNew = 1;
const uint8 xDeleted = 2;
const uint8 xModified = 4;
const uint8 xExisting = 8;
}
Für diese Konstanten können Sie jedoch nicht den Schalter verwenden. Wählen Sie also am Ende Ihr Gift... :-p