В проекте С++, над которым я работаю, у меня есть флаг типа значения, который может иметь четыре значения. Эти четыре флага могут быть объединены. Флаги описывают записи в базе данных и могут быть:
- новая запись
- удаленная запись
- измененная запись
- существующая запись
Теперь для каждой записи я хочу сохранить этот атрибут, поэтому я мог бы использовать перечисление:
enum { xNew, xDeleted, xModified, xExisting }
Однако в других местах кода мне нужно выбрать, какие записи должны быть видимыми для пользователя, поэтому я хотел бы передать это как один параметр, например:
showRecords(xNew | xDeleted);
Итак, кажется, у меня есть три возможных привязанности:
#define X_NEW 0x01
#define X_DELETED 0x02
#define X_MODIFIED 0x04
#define X_EXISTING 0x08
или
typedef enum { xNew = 1, xDeleted, xModified = 4, xExisting = 8 } RecordType;
или
namespace RecordType {
static const uint8 xNew = 1;
static const uint8 xDeleted = 2;
static const uint8 xModified = 4;
static const uint8 xExisting = 8;
}
Требования к пространству важны (byte vs int), но не имеют решающего значения. С помощью определений я теряю безопасность типа, а при enum
я теряю некоторое пространство (целые числа) и, вероятно, должен отбрасывать, когда хочу выполнить побитовое действие. С const
я думаю, что также теряю безопасность типов, так как случайный uint8
может попасть по ошибке.
Есть ли какой-нибудь другой более чистый способ?
Если нет, что бы вы использовали и почему?
P.S. Остальная часть кода представляет собой довольно чистый современный С++ без #define
s, и я использовал пространства имен и шаблоны в нескольких местах, поэтому они тоже не могут быть и речи.