Ответ 1
Учитывая ваше описание ситуации, я бы сказал, что использование static const
- это хороший подход. В С++ 11 вы можете изменить его на static constexpr
, чтобы подчеркнуть его константу времени компиляции, хотя в результате этого ничего не изменится.
Если вы ссылаетесь на myclass::kMyClassContant_
где-то в коде таким образом, который имеет отношение к правилу с одним определением (odr), esp. в контекстах, требующих ссылки (включая const-reference), компилятор будет жаловаться на отсутствие определения константы. В этом случае недостаточно объявить и инициализировать его внутри класса. Это может заставить вас отделить объявление и определение:
// mycode.h
class myclass {
private:
static const uint16_t kMyClassConstant_;
};
// mycode.cpp
const uint16_t myclass::kMyClassConstant_ = 0xBEEF;
Чтобы избежать проблем с сохранением отдельных деклараций и определений, некоторые люди предпочитают объявлять встроенную функцию constexpr вместо фактической переменной:
// mycode.h
class myclass {
private:
static constexpr uint16_t kMyClassConstant_()
{ return 0xBEEF; }
};
Это правильная работа для многих проблем, связанных с odr, и это не приводит к потере производительности. Является ли это действительно полезным, зависит от того, сколько издержек состоит в том, чтобы поддерживать отдельные декларации и определения обычной статической константы. Если вы ожидаете, что ваши константы никогда не будут меняться по мере развития вашего кода, предпочтительнее использовать обычные статические константы с отдельными определениями. Но если вы часто изменяете определения констант, необходимо повторно скомпилировать файл определения и перенастроить его во все соответствующие части проекта, вы можете подумать над предлагаемым выше решением на основе функций в качестве лучшей альтернативы.
Последний комментарий к типу данных: принудительное его использование в 16 бит с использованием std::uint16_t
может оказаться полезным, если вам нужно хранить много этих значений в компактной форме. В противном случае фактический размер может не иметь особого значения, и в этом случае std::uint_fast16_t
(который может быть больше 16 бит) может быть лучше.