C++ const используется дважды в объявлении статического массива
Я видел const
используется дважды в объявлении static
массив раньше и теперь, когда я создаю свой собственный статический массив, мне интересно, почему const понадобится дважды в некоторых ситуациях.
имеет ли значение наличие массива указателей?
a. static const TYPE name[5];
b. static const TYPE const name[5];
c. static const TYPE* name[5];
d. static const TYPE* const name[5];
насколько я понимаю, это b.
недопустимо, но если использование const дважды допустимо, какова его цель?
4 ответов
const тип* x;
означает, что вещь, на которую указывает x, является const.
тип * const x;
означает, что указатель x является const.
объединение 2 Вы получаете:
const тип * const x;
означает, что указатель и указанная вещь являются const.
вы можете применить любой CV-квалификатор (const
или volatile
) к любому типу, включая CV-квалифицированные типы -- но не в таком же объявлении. Однако они связываются сильнее, чем любой оператор, с точки зрения приоритета и могут применяться с обеих сторон квалифицированного типа:
// Let T by any type:
T const tr;
const T tl;
const T const tlr; // only in C
const const const const const T t5; // only in C
typedef const T CT;
CT const tcc; // fine, although CT was already const
объявить то же самое, константа T
. Если T
уже есть cv-квалификаторы, это не меняет значения дополнительной квалификации.
теперь к старшинству; вы можно сказать: "я хочу указатель на константу T
":
const T (* tp);
который обычно пишется как
const T* tp;
потому что const
связывает сильнее, чем *
в любом случае. В том же шаблоне вы можете определить переменную, которая является "константой, но указывает на изменяемый T
":
T (* const tp) = 0; // must be initialised, because tp is immutable
который обычно пишется как
T* const tp = 0;
в том же ключе оператор индекса []
применяется -- с тем же приоритетом, что и в выражения.
в первом блоке кода у вас есть дублирующие const
во второй строке, которая не имеет никакого эффекта. (На самом деле, хорошие компиляторы предупредят вас об этом.) Вы объявляете массив из 5 const TYPE
s, Вот и все.
второй блок кода имеет два различных сценария: первая строка создает массив из пяти mutable указатели const TYPE
s, в то время как последний делает массив из пяти постоянный указатели const TYPE
s.
обратите внимание, что вы должны инициализировать массив констант: поскольку вы не можете изменить значения позже, нет смысла определять их неинициализированными.
используя const
дважды на типе является незаконным в C++ 2003, но законным в C++ 2011 (см. 7.1.6.1 [decl.типа.cv] пункт 1: "избыточные cv-квалификации игнорируются."). Когда вы используете
static const TYPE const name[5];
ты TYPE
дважды постоянной. Обратите внимание, однако, что это объявление является незаконным и в C++ 2011, потому что вам нужно инициализировать const
объект при его декларировании. Смысл
const TYPE
и
TYPE const
абсолютно эквивалентно: в обоих случаях вы делаете TYPE
объект постоянным. Для согласованности я всегда ставлю const
вправо, потому что каждый, кроме верхнего уровня типа const
должен быть поставлен на правую сторону (ну, если некоторые руководящие принципы кодирования не требуют по-другому, но я борюсь с глупыми руководящими принципами кодирования).
при использовании указателей, думает, что стал другим. Существует два типа: Тип, указываемый на тип, и указатель. Каждый из них может быть сделан const
отдельно:
TYPE const* ptr1(0); // non-const pointer to const TYPE
TYPE* const ptr2(0); // const pointer to non-const TYPE
TYPE const* const ptr3(0); // const pointer to const TYPE
лучший способ выяснить, что это сделал const
читать объявление типа справа налево. Конечно, это предполагает, что const
спецификаторы помещаются в нужное место. Вы можете заменить const
by volatile
или const volatile
в обсуждении выше и то же самое рассуждение применяется.