Справочное руководство по C++ | страница 46



Таким образом, описание некоторого идентификатора имеет вид

>T D

где T обозначает тип, а D - описатель. Если в описании D есть идентификатор без скобок, то тип этого идентификатора есть T.

В описании, где D имеет вид

>( D1 )

тип D1 такой же, как и тип D. Наличие скобок не меняет типа заключенного в них имени-из-описателя, но для сложных описателей оно может повлиять на порядок применения операций.

R.8.2.1 Указатели

В описании T D, в котором D имеет вид

>* список-спецификаций-cv >opt D1

тип описываемого идентификатора есть

"… список-спецификаций-cv указатель на T". Конструкция список-спецификаций-cv относится к указателю, а не к указуемому объекту.

Например, в описаниях

>const ci = 10, *pc = &ci, *const cpc = pc;

>int i *p, *const cp = &i;

определяются: ci как константа целое; pc как указатель на константу целое; cpc как константа указатель на константу целое; i как целое; p как указатель на целое; и cp как константа указатель на целое. После инициализации значения ci, cpc и cp не могут быть изменены. Значение pc можно изменять так же, как и значение объекта, на который указывает cp. Приведем примеры допустимых операций:

>i = ci;

>*cp = ci;

>pc++;

>pc = cpc;

>pc = p;

Недопустимы следующие операции:

>ci = 1; // ошибка

>ci++; // ошибка

>*pc = 2; // ошибка

>cp = &ci; // ошибка

>cpc++; // ошибка

>p = pc; // ошибка

Каждая из этих операций недопустима или потому, что она изменяет значение объекта, описанного со спецификацией const, или потому, что делает такое изменение возможным позднее с помощью указателя, настроенного на объект без спецификации const.

Аналогична ситуация со спецификацией volatile.

Обратитесь к §R.5.17 и §R.8.4.

Нельзя описывать указатели на ссылки (§R.8.2.2) или указатели на битовые поля (§R.9.6).

R.8.2.2 Ссылки

В описании T D, в котором D имеет вид

>& список-спецификаций-cv >opt D1

тип описываемого идентификатора есть "…список-спецификаций-cv ссылка на T". Тип void& недопустим.

Например, во фрагменте

>void f(double& a) { a += 3.14; }

>//…

>double d = 0;

>f(d);

a описывается как параметр, являющийся ссылкой, поэтому вызов f(d) приведет к увеличению d на 3.14. Во фрагменте

>int v[20];

>//…

>int& g(int i) { return v[i]; }

>//…

>g(3) = 7;

описывается: функция g() возвращает ссылку на целое; поэтому оператор g() = 7; присвоит 7 четвертому элементу массива v. Рассмотрим следующий программный фрагмент:

>struct link {

> link* next;

>};

>link* first;


>void h(link*& p) // `p' ссылка на указатель

>{

> p-›next = first;

> first = p;

> p = 0;

>}


>void k()