использование объявления для общедоступных статических постоянных членов класса

#c #class #static #constants

#c #класс #статический #константы

Вопрос:

Human определяет множество общедоступных статических констант:

 class Human
{
public:

static const int NUM_FINGERS = 10;
static const int NUM_TOES = 10;
static const int NUM_HANDS = 2;
static const int NUM_FEET = 2;

//The rest of the human class here
};
  

Несвязанный класс часто использует их и должен указывать их с именем класса:

 class Unrelated
{
public:
int SomeFunction()
{
//Many uses of Human's public static constants
return Human::NUM_FINGERS   Human::NUM_TOES   Human::NUM_HANDS   Human::NUM_FEET;
}
};
  

В случае пространства имен вы можете:

 using namespace blah;
  

Существует ли эквивалент для такого предупреждения?

 using namespace Human; //wrong

int Unrelated::SomeFunction()
{
return NUM_FINGERS   NUM_TOES   NUM_HANDS   NUM_FEET;
}
  

Считается ли плохим программированием определять кучу констант таким образом?

Комментарии:

1. Не у всех людей есть 10 пальцев на руках, 10 пальцев на ногах, 2 руки и 2 ноги.

Ответ №1:

Несвязанный класс часто использует их и должен указывать их имя класса.

Что в этом плохого? Подумайте об этом так: какое имя переменной лучше, nt или num_toes ? Дальнейшее уточнение имени с помощью класса Human (или пространства Human имен, если вы меняете свой класс на пространство имен) — это хорошо, а не плохо. Это помогает компилятору, это помогает вам как программисту избежать случайного столкновения с каким-либо другим именем, и это помогает другому человеку, который пытается понять ваш код.

Что касается имен NUM_FINGERS и т. Д.: я рекомендую не использовать ALL_CAPS . Когда-нибудь кто-нибудь напишет NUM_FINGERS макрос, который превратит ваш код в тарабарщину. Зарезервируйте имена ALL_CAPS для макросов, а затем старайтесь избегать макросов.

Комментарии:

1. Кто является случайным участником downvoter? Рекомендация использовать ALL_CAPS только для макросов и макросов не только моя. Вы найдете это во многих, многих стандартах кодирования.

Ответ №2:

Предполагая, что Unrelated это действительно Unrelated_but_about_Humans так, вы можете просто сказать «У меня те же константы, Human что и «:

 class Unrelated
{
private:
    static const int NUM_FINGERS = Human::NUM_FINGERS;
    static const int NUM_TOES = Human::NUM_TOES;
    static const int NUM_HANDS = Human::NUM_HANDS;
    static const int NUM_FEET = Human::_NUM_FEET;
}
  

(Замечания других ответов относительно хрупкости и т. Д. Остаются в силе.)

Комментарии:

1. Я об этом не подумал. Я думаю, что это действительно не связано само по себе. Это связано, но оно должно быть в своем собственном классе, и оно не может быть дочерним классом, потому что основным классом является объект app. Таких классов будет всего 3, поэтому мне пришлось бы переопределить константы во всех трех. Может быть, оно того не стоит.

2. Вы могли бы создать пространство имен с именем HumanConstants и поместить туда константы. Затем have Human и другие классы импортируют это пространство имен.

Ответ №3:

Это несколько зависит от ситуации.

Константы относятся к классу Human, поэтому вполне логично, что они «принадлежат» ему, а использование имен в пространстве имен (Human::NUM_ARMS ) делает их использование однозначным. (Представьте, что произойдет, если вы введете новые классы, такие как Octopus. Вы бы использовали Octopus::NUM_ARMS , что было бы 8, а не 2. Слава богу за локализованные имена классов / пространств имен!)

Конечно, в ситуации с человеком / осьминогом вы можете пересмотреть использование констант и вместо этого использовать класс / интерфейс Animal с виртуальным методом GetNumArms(), который каждый может переопределить. Это позволило бы вашему клиентскому коду быть только слабо связанным с человеком и осьминогом и хорошо работать для обоих типов животных. Это позволило бы базовым константам быть частными для каждого из этих классов.

Или, если вы пишете код в другом направлении, подумайте, что вычисляет внешний класс. Чья ответственность должна быть за это вычисление? Возможно, вам следует добавить вычисление в класс Human (например Human::GetNumLimbs() , Human::GetNumBodyParts() )

Наконец, мы все перешли от 1970-х годов, поэтому я бы рекомендовал использовать более читаемый стиль для констант (например Human::cNumFeet , вызывает гораздо меньшее кровотечение из глаз, чем Human::NUM_FEET , и не будет легко ошибочно принят за любые макросы, которые у вас есть)

Ответ №4:

Нет, сглаживание пространств имен, т. Е. Использование using namespace , особенно в глобальной области, считается плохим программированием. Если это константа в X классе, напишите X::constant , иначе вы просто затрудняете читаемость (и рискуете конфликтами именования).

Ответ №5:

Считается ли плохим программированием определять кучу констант таким образом?

Действительно, ваш второй несвязанный класс использует константы из другого класса.Это тесно связанная зависимость. если первый класс по каким-либо причинам модифицируется для удаления / рефакторинга констант, ваш второй класс также будет затронут. Избегайте таких зависимостей.