Константы в C / C ++ - PullRequest
       4

Константы в C / C ++

1 голос
/ 14 октября 2010

Сколько существует различных способов определения констант в C или C ++?

Мне уже известно об использовании ключевого слова const и директивы #define. Я где-то слышал, что есть еще два способа определения констант, но я никогда не видел других. Есть ли другие?

Ответы [ 3 ]

6 голосов
/ 14 октября 2010

enum, как в enum { some_constant= 2 };

РЕДАКТИРОВАТЬ: я также забыл о добавлении constexpr и пользовательских литералов в стандарт C ++ 0x. Так что на самом деле есть три дополнительных способа.

3 голосов
/ 14 октября 2010

Для базового неформального значения "константа" у вас есть #define, const и enum, как уже упоминалось в других ответах.

Но, по крайней мере, когда я пишу это, никто еще не обсуждал, как их использовать.

Во-первых, я уверен, что вы знаете, что макросы - это зло, поэтому я не буду вдаваться в подробности: просто скажите «нет» #define (как средство определения констант).

Во-вторых, enum пригодится, когда вам нужно определить постоянный static член целочисленного типа в коде, который должен быть переносим на старые компиляторы.

В-третьих, для формального значения "определить" есть, возможно, очень удивительная тонкость:

struct Blah
{
    static int const x = 42;     // This is just a declaration, not a definition.
};

int const Blah::x;               // This is a definition (yes!).

int main()
{
    // Use Blah::x here.
}

Часть тонкости - это обмен визуальной формой чистого объявления с определением. Практически в любом другом контексте это объявление с инициализацией, которое также является определением. Но не для этого статического члена целочисленного типа!

И часть тонкости заключается в том, что без определения где-то вы не можете формально взять адрес Blah::x; это определение, которое формально дает ему хранение.

И, часть тонкости заключается в том, что ни по какой веской причине, кроме исторической случайности, вы можете сделать выше только для целочисленных типов, а не, например, для double или строка, что угодно.

struct Blah
{
    static double const x = 3.14;  // !CAN NOT DO THIS IN C++98.
};

Чтобы эффективно создать постоянную члена, скажем, типа double, вы можете использовать шаблонную постоянную идиома в качестве обходного пути. Эффективно выполняя работу компилятора, то, что он в принципе мог бы переписать выше как. Это выглядит так:

template< class Dummy >
struct BlahConstants
{
    static double const x;
};

template< class Dummy >
double const BlahConstants< Dummy >::x = 3.14;

struct Blah
    : BlahConstants< void >
{
    // Whatever.
};

int main()
{
    // Use Blah::x here.
}

Например, вы можете использовать этот трюк для полного определения класса Blah в заголовочном файле.

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

Приветствия & hth.,

1 голос
/ 14 октября 2010

В C есть числовые константы и строковые литералы (например, int i = 5, 5 - это константа). Возможно, это то, что они имели в виду.

...