best practices по поводу констант
От: FrozenHeart  
Дата: 24.01.14 10:00
Оценка:
Здравствуйте.

Вопрос по дизайну и правилам хорошего тона.

До недавних пор всё время придерживался политики "любой литерал в коде должен быть представлен в виде соответствующего макроса, добавленного в предкомпиляционный заголовочный файл или в какой-нибудь common.h". Делал я так даже в том случае, если контекст использования данной константы (по крайней мере, на текущий момент) сильно ограничен (например, она используется лишь внутри одной функции / класса / etc). С недавних пор решил поступать иначе — заводить константные объекты внутри этих самых модулей:

void foo()
{
    const int SOME_CONSTANT_VALUE = 0;
    // ...
}


class Foo
{
public:
    Foo() : SOME_CONSTANT_VALUE(0) {}

private:
    const int SOME_CONSTANT_VALUE;
};


Такой вариант мне тоже не очень нравится. Например, в классах, при наличии довольно большого кол-ва констант, будет(ут) довольно некрасивый(ые) конструктор(ы):

class Foo
{
public:
    Foo()
    : SOME_CONSTANT_VALUE(0)
    , ANOTHER_CONSTANT_VALUE(0.0)
    , YET_ANOTHER_CONSTANT_VALUE(0.0)
    , SOME_CONSTANT_VALUE_AGAIN(0.0) {}

private:
    const int SOME_CONSTANT_VALUE;
    const double ANOTHER_CONSTANT_VALUE;
    const double YET_ANOTHER_CONSTANT_VALUE;
    const double SOME_CONSTANT_VALUE_AGAIN;
};


Да, с delegating costructors из C++11 такое можно написать всего лишь в одном конструкторе, но особо положения дел это не меняет, на мой взгляд.

Более того, когда все константы вынесены в отдельный заголовочный файл, их проще находить и редактировать. При чтении же конкретного модуля, я думаю, не составит труда перейти на определение символа под курсором.

Да и смотрится это как-то, честно говоря, странно — вроде и член класса, но при этом константа. Не называть же объект как-нибудь _SOME_CONSTANT_VALUE, чтобы подчеркнуть и то, и другое?

Как Вы поступаете в подобных случаях?
avalon/1.0.433
Re: best practices по поводу констант
От: night beast СССР  
Дата: 24.01.14 10:10
Оценка: 1 (1) +6
Здравствуйте, FrozenHeart, Вы писали:

FH>Как Вы поступаете в подобных случаях?


использую enum внутри класса.
ЗАГЛАВНЫЕ_БУКВЫ применяю исключительно для макросов.
Re: best practices по поводу констант
От: watchmaker  
Дата: 24.01.14 10:13
Оценка: +2
Здравствуйте, FrozenHeart, Вы писали:

FH>
FH>class Foo
FH>{
FH>public:
FH>    Foo() : SOME_CONSTANT_VALUE(0) {}

FH>private:
FH>    const int SOME_CONSTANT_VALUE;
FH>};
FH>


FH>Такой вариант мне тоже не очень нравится.

Ну так действительно делать не имеет большого смысла. Ведь если член имеет одно и то же значение для всех экземпляров класса, то незачем его хранить в каждом из них:
class Foo {
    static const int SOME_CONSTANT_VALUE = 0;
};

И на конструкторы это никак теперь не влияет.


FH>Более того, когда все константы вынесены в отдельный заголовочный файл, их проще находить и редактировать. При чтении же конкретного модуля, я думаю, не составит труда перейти на определение символа под курсором.

Ну есть константы на века, а есть константные параметры, через которые настраивается поведение программы, и которые-таки иногда меняются. Вполне допустимо, что первые определены максимально близко к месту использования, а вторые собраны где-то в отдельном файле в библиотеке. И так, и так приходится делать.
Re: best practices по поводу констант
От: Vzhyk  
Дата: 24.01.14 10:59
Оценка:
Здравствуйте, FrozenHeart, Вы писали:

FH>Как Вы поступаете в подобных случаях?

Зависит от логики. Иногда const, иногда enum, иногда лучше прямо в коде литерал (есть случаи когда литерал более понятен читающему, чем длинное_мнемоническое_имя_важной_константы).
Правило всегда одно, компилятору пофиг, а программу будут читать люди и она им должна быть понятна.
Re: best practices по поводу констант
От: niXman Ниоткуда https://github.com/niXman
Дата: 24.01.14 12:07
Оценка: +2
Здравствуйте, FrozenHeart, Вы писали:

'static const'
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: best practices по поводу констант
От: niXman Ниоткуда https://github.com/niXman
Дата: 24.01.14 14:53
Оценка:
но для целочисленных все же предпочитаю enum.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: best practices по поводу констант
От: VladFein США  
Дата: 24.01.14 17:50
Оценка: +1 :)
Здравствуйте, niXman, Вы писали:

X>но для целочисленных все же предпочитаю enum.


enum вместо static const <type> — это грязный хэк, доставщхийся нам со времён компиляторов, не умеющих инициализировать константные переменные по месту объявления.
Re[4]: best practices по поводу констант
От: night beast СССР  
Дата: 24.01.14 18:09
Оценка:
Здравствуйте, VladFein, Вы писали:

X>>но для целочисленных все же предпочитаю enum.


VF>enum вместо static const <type> — это грязный хэк, доставщхийся нам со времён компиляторов, не умеющих инициализировать константные переменные по месту объявления.


static const double?
Re[4]: best practices по поводу констант
От: niXman Ниоткуда https://github.com/niXman
Дата: 24.01.14 18:14
Оценка: 12 (2) +1
Здравствуйте, VladFein, Вы писали:

VF>enum вместо static const <type> — это грязный хэк, доставщхийся нам со времён компиляторов, не умеющих инициализировать константные переменные по месту объявления.

как скажешь. даже спорить с тобой не стану.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[5]: best practices по поводу констант
От: VladFein США  
Дата: 24.01.14 19:26
Оценка: +1 :))
Здравствуйте, night beast, Вы писали:

NB>Здравствуйте, VladFein, Вы писали:


X>>>но для целочисленных все же предпочитаю enum.


VF>>enum вместо static const <type> — это грязный хэк, доставщхийся нам со времён компиляторов, не умеющих инициализировать константные переменные по месту объявления.


NB>static const double?


enum { f = 3.14; } ???
Re[5]: best practices по поводу констант
От: VladFein США  
Дата: 24.01.14 19:32
Оценка:
Здравствуйте, niXman, Вы писали:

VF>>enum вместо static const <type> — это грязный хэк, доставщхийся нам со времён компиляторов, не умеющих инициализировать константные переменные по месту объявления.

X>как скажешь.
Я именно так и сказал.

X>даже спорить с тобой не стану.

А что так? Не уважаешь???
Re[6]: best practices по поводу констант
От: niXman Ниоткуда https://github.com/niXman
Дата: 24.01.14 19:57
Оценка: :)
Здравствуйте, VladFein, Вы писали:

VF>enum { f = 3.14; } ???

1. и какой компилятор такое компилирует?
2. точку с запятой не там поставил.
3. не ведаешь что творишь.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[7]: best practices по поводу констант
От: VladFein США  
Дата: 24.01.14 20:12
Оценка: +1
Здравствуйте, niXman, Вы писали:

VF>>enum { f = 3.14; } ???

X>1. и какой компилятор такое компилирует?

Вырвано из контекста. Это был мой (саркастический) ответ на "static const double?"

NB>static const double?
enum { f = 3.14; } ???

Re[6]: best practices по поводу констант
От: night beast СССР  
Дата: 25.01.14 04:02
Оценка:
Здравствуйте, VladFein, Вы писали:

X>>>>но для целочисленных все же предпочитаю enum.


VF>>>enum вместо static const <type> — это грязный хэк, доставщхийся нам со времён компиляторов, не умеющих инициализировать константные переменные по месту объявления.


NB>>static const double?


VF>enum { f = 3.14; } ???


да легко:
enum { f = 3140 };

static double f () { return 3.14; }
Re[7]: best practices по поводу констант
От: TarasB  
Дата: 25.01.14 07:40
Оценка:
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, VladFein, Вы писали:


VF>>enum { f = 3.14; } ???

X>1. и какой компилятор такое компилирует?

Ты всегда всё воспринимаешь всерьёз, даже когда написано зелёным текстом?
Re[6]: best practices по поводу констант
От: Vzhyk  
Дата: 25.01.14 09:53
Оценка:
1/24/2014 10:32 PM, VladFein пишет:

> А что так? Не уважаешь???

Для этого сначала налить надо, а потом уже и обсудить можно.
Posted via RSDN NNTP Server 2.1 beta
Re[4]: best practices по поводу констант
От: Andrew S Россия http://alchemy-lab.com
Дата: 25.01.14 21:40
Оценка: +1 -1
X>>но для целочисленных все же предпочитаю enum.

VF>enum вместо static const <type> — это грязный хэк, доставщхийся нам со времён компиляторов, не умеющих инициализировать константные переменные по месту объявления.


Те времена все еще с нами. Рекомендую ознакомиться.
http://www.rsdn.ru/forum/cpp/5350623
Автор: Abyx
Дата: 02.11.13
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: best practices по поводу констант
От: rg45 СССР  
Дата: 25.01.14 22:12
Оценка: 3 (1) +1
Здравствуйте, VladFein, Вы писали:

X>>но для целочисленных все же предпочитаю enum.


VF>enum вместо static const <type> — это грязный хэк, доставщхийся нам со времён компиляторов, не умеющих инициализировать константные переменные по месту объявления.


Есть одно но. Согласно п.9.4.2/4 стандарта (п.9.4.2/3 в ст. 2003 г.), если даже объявление статической целочисленной константы — члена класса имеет инициализатор:
class A
{
  static const int foo = 42;
};

все равно определение этого статического члена обязано быть сделано за пределами класса:
const int A::foo;

И в этом плане определение целочисленных констант при помощи enum имеет очевидное преимущество.
--
Справедливость выше закона. А человечность выше справедливости.
Re[5]: best practices по поводу констант
От: night beast СССР  
Дата: 26.01.14 05:36
Оценка: +1
Здравствуйте, rg45, Вы писали:

X>>>но для целочисленных все же предпочитаю enum.


VF>>enum вместо static const <type> — это грязный хэк, доставщхийся нам со времён компиляторов, не умеющих инициализировать константные переменные по месту объявления.


R>Есть одно но. Согласно п.9.4.2/4 стандарта (п.9.4.2/3 в ст. 2003 г.), если даже объявление статической целочисленной константы — члена класса имеет инициализатор:

R>все равно определение этого статического члена обязано быть сделано за пределами класса:

мда. не думал что все настолько печально.
Re[5]: best practices по поводу констант
От: VladFein США  
Дата: 27.01.14 14:36
Оценка:
Здравствуйте, rg45, Вы писали:

R>И в этом плане определение целочисленных констант при помощи enum имеет очевидное преимущество.


что не мешает этому оставаться грязным хэком...
Re[6]: best practices по поводу констант
От: rg45 СССР  
Дата: 27.01.14 15:19
Оценка: +2
Здравствуйте, VladFein, Вы писали:

R>>И в этом плане определение целочисленных констант при помощи enum имеет очевидное преимущество.


VF>что не мешает этому оставаться грязным хэком...


Тут уже кто как ярлыки развесит...
--
Справедливость выше закона. А человечность выше справедливости.
Re: best practices по поводу констант
От: Lepsik Индия figvam.ca
Дата: 28.01.14 19:54
Оценка: +1 -1
FH>Вопрос по дизайну и правилам хорошего тона.


static const int  s_nLocalCounter    = 1; 
static const char s_szLocalName[]    = "local name"; 

const int        g_nGloabalCounter  = 1;
Re[2]: best practices по поводу констант
От: rg45 СССР  
Дата: 29.01.14 12:53
Оценка: 1 (1) :)
Здравствуйте, Lepsik, Вы писали:

L>
L>static const int  s_nLocalCounter    = 1; 
L>static const char s_szLocalName[]    = "local name"; 

L>const int        g_nGloabalCounter  = 1; 
L>




Во-первых,
const int g_nGloabalCounter  = 1;

это то же самое, что и
static const int g_nGloabalCounter  = 1;

поэтому не очень понятен принцип, по которому ты в одних случаях используешь префикс "s_", а в других "g_".


А во-вторых, современный C++ движется в сторону обобщенного программирования и обобщенных алгоритмов, к абстрагированию от конкретных типов. Поэтому ИМХО, использование префиксов, описывающих тип (а тем более связывание или storage duration) — это уже вчерашний день, а не best practices.
--
Справедливость выше закона. А человечность выше справедливости.
Re[3]: best practices по поводу констант
От: Roman Odaisky Украина  
Дата: 30.01.14 16:03
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>А во-вторых, современный C++ движется в сторону обобщенного программирования и обобщенных алгоритмов, к абстрагированию от конкретных типов. Поэтому ИМХО, использование префиксов, описывающих тип (а тем более связывание или storage duration) — это уже вчерашний день, а не best practices.


А что не так в g_ и m_? И венгерская нотация — тоже нужная вещь.
До последнего не верил в пирамиду Лебедева.
Re[4]: best practices по поводу констант
От: VladFein США  
Дата: 30.01.14 17:32
Оценка: -1
Здравствуйте, Roman Odaisky, Вы писали:

RO>А что не так в g_ и m_? И венгерская нотация — тоже нужная вещь.


Во-первых, rg45 сравнивал "s_" и "g_", ошибочно утверждая, что между ними нет разницы (разница в видимости за пределами единицы трансляции).
Во-вторых, давайте начнём "спор" о венгерской нотации в отдельной теме, сразу в СВ
Re[5]: best practices по поводу констант
От: uzhas Ниоткуда  
Дата: 30.01.14 17:45
Оценка: 6 (1) +1
Здравствуйте, VladFein, Вы писали:

VF>Во-первых, rg45 сравнивал "s_" и "g_", ошибочно утверждая, что между ними нет разницы (разница в видимости за пределами единицы трансляции).

const объекты по умолчанию имеют внутреннее связывание (internal linkage), так же как и static переменные

VF>Во-вторых, давайте начнём "спор" о венгерской нотации в отдельной теме, сразу в СВ

+1
Re[4]: best practices по поводу констант
От: rg45 СССР  
Дата: 30.01.14 17:46
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

R>>А во-вторых, современный C++ движется в сторону обобщенного программирования и обобщенных алгоритмов, к абстрагированию от конкретных типов. Поэтому ИМХО, использование префиксов, описывающих тип (а тем более связывание или storage duration) — это уже вчерашний день, а не best practices.


RO>А что не так в g_ и m_? И венгерская нотация — тоже нужная вещь.



Думаю, как бы так ответить, чтоб и кратко и, в то же время, не провоцировать ненужных дискуссий. Скажем так, строго доказательства у меня нет, но есть вера в то, что без этих префиксов можно обойтись. Префикс m_ я и сам широко использую, но если подумать, то в хорошо спроектированном коде и он не нужен. От g_ и s_ так точно можно избавиться. Венгерская нотация — достаточно большой комплекс различных правил, дискутировать о нем можно долго. Я бы ограничился только рассмотрением вопроса кодирования типов переменных в их именах: "d", "n", "p", "sz" и прочие "абырвалги" — все эти шифровки нагружают лишними подробностями и утомляют при чтении. Хочется видеть максимально декларативный, самодокументированный и приближенный к человеческой речи код, где функции и переменные названы человеческими словами и описывают сущности предметной области.
--
Справедливость выше закона. А человечность выше справедливости.
Re[5]: best practices по поводу констант
От: rg45 СССР  
Дата: 30.01.14 17:52
Оценка: 6 (1)
Здравствуйте, VladFein, Вы писали:

VF>Во-первых, rg45 сравнивал "s_" и "g_", ошибочно утверждая, что между ними нет разницы (разница в видимости за пределами единицы трансляции).


Никаких ошибочных утверждений не было. Согласно стандарту, как старому, так и новому, если переменная объявлена с модификатором const и при этом явно не объявлена как extern, то она получает внутренне связывание (т.е. static).
--
Справедливость выше закона. А человечность выше справедливости.
Re[6]: best practices по поводу констант
От: VladFein США  
Дата: 30.01.14 20:56
Оценка: +1
Здравствуйте, rg45, Вы писали:

R>Никаких ошибочных утверждений не было. Согласно стандарту, как старому, так и новому, если переменная объявлена с модификатором const и при этом явно не объявлена как extern, то она получает внутренне связывание (т.е. static).


Упс... Прошу прощения. Век живи — ...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.