Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#15| Dragon God
Demon's Souls |#14| Flamelurker
Demon's Souls |#13| Storm King
Demon's Souls |#12| Old Monk & Old Hero

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Страустрап Б. Весь текст 579.17 Kb

Язык С++

Предыдущая страница Следующая страница
1 ... 36 37 38 39 40 41 42  43 44 45 46 47 48 49 50

     7.14 Операции присваивания

  Есть много  операций присваивания,  все группируют слева направо.
Все в  качестве левого  операнда требуют  lvalue, и  тип  выражения
присваивания тот  же, что  и у  его левого  операнда. Это lvalue не
может ссылаться  на константу (имя массива, имя функции или const).
Значением является  значение, хранящееся  в левом  операнде  просле
выполнения присваивания.

  выражение_присваивания:
      выражение  операция_присваивания  выражение

  операция_присваивания: одна из
      =  +=  -=  *=  /=  %=  >>=  <<=  &=  ~=  |=

  В простом  присваивании с  = значение  выражения  замещает  собой
значение объекта,  на который ссылается операнд в левой части. Если
оба  операнда   имеют  арифметический  тип,  то  при  подготовке  к
присваиванию правый  операнд  преобразуется  к  типу  левого.  Если
аргумент в  левой части  имеет указательный  тип, аргумент в правой
части должен  быть  того  же  типа  или  типа,  кторый  может  быть
преобразован к  нему, см.  #6.7. Оба  операнда могут быть объектами
одного класса.  Могут присваиваться  объекты некоторых  производных
классов; см. #8.5.3.
  Присваивание   объекту   типа   "указатель   на   ..."   выполнит
присваивание объекту, денотируемому ссылкой.
  Выполнение выражения  вида E1  op= E2  можно представить себе как
эквивалентное E1 = E1 op (E2); но E1 вычисляется только один раз. В
+= и  -= левый  операнд может  быть указателем,  и  в  этом  случае
(интегральный) правый  операнд преобразуется так, как объяснялось в
#7.4; все  правые операнды и не являющиеся указателями левые должны
иметь арифметический тип.

     7.15 Операция запятая

  запятая_выражение:
      выражение , выражение

  Пара выражений,  разделенных запятой,  вычисляется слева направо,
значение левого  выражения  теряется.  Тип  и  значение  результата
являются  типом   и  значением   правого  операнда.   Эта  операция
группирует  слева   направо.  В   контексте,  где   запятая   имеет
специальное значение,  как например в списке фактических параметров
функции  (#7.1)    и  в  списке  инициализаторов  (#8.6),  операция
запятая, как  она описана в этом разделе, может появляться только в
скобках; например,

  f (a,(t=3,t+2),c)

имеет три параметра, вторым из которых является значение 5.

                             - стр 273 -

     7.16 Перегруженные операции

  Большинство операций  может быть  перегружено, то  есть,  описано
так, чтобы  они получали  в качестве операндов объекты классов (см.
#8.5.11).  Изменить   приоритет  операций   невозможно.  Невозможно
изменить смысл  операций при  применении их к неклассовым объектам.
Предопределенный смысл операций = и & (унарной) при применении их к
объектам классов может быть изменен.
  Эквивалентность операций, применяемых к основным типам (например,
++a эквивалентно  a+=1), не  обязательно выполняется  для операций,
применяемых  к   классовым  типам.  Некоторые  операции,  например,
присваивание, в  случае применения  к основным типам требуют, чтобы
операнд был  lvalue; это  не требуется  для операций, описанных для
классовых типов.

     7.16.1 Унарные операции

  Унарная  операция,   префиксная  или   постфиксная,  может   быть
определена или  с помощью функции члена (см. #8.5.4), не получающей
параметров, или  с помощью  функции друга (см. #8.5.10), получающей
один параметр,  но не  двумя способами одновременно. Так, для любой
унарной  операции   @,  x@   и  @x   могут  интерпретироваться  как
x.операция@() или  операция@(x). При  перегрузке операций  ++ и  --
невозможно различить префиксное и постфиксное использование.

     7.16.2 Бинарные операции

  Бинарная операция  может быть  определена или  с помощью  функции
члена (см. #8.5.4), получающей один параметр, или с помощью функции
друга (см. #8.5.9), получающей два параметра, но не двумя способами
одновременно. Так,  для любой  бинарной операции  @, x@y может быть
проинтерпретировано как x.операция@(y) или операция@(x,y).

     7.16.3 Особые операции

  Вызов функции

  первичное_выражение ( список_выражений opt )

и индексирование

  первичное_выражение [ выражение ]

считаются  бинарными   операциями.  Именами   определяющей  функции
являются соответсвенно  operator()   и operator[]. Обращение x(arg)
интерпретируется как  x.operator()(arg) для  классового объекта  x.
Индексирование x[y] интерпретируется как x.operator[](y).

                             - стр 274 -


                         8. ОПИСАНИЯ

  Описания используются  для  определения  интерпретации,  даваемой
каждому идентификатору;  они  не  обязательно  резервируют  память,
связанную с идентификатором. Описания имеют вид:

  описание:
      спецификаторы_описания opt список_описателей opt ;
      описание_имени
      asm_описание

  Описатели в списке_описателей содержат идентификаторы, подлежащие
описанию. Спецификаторы_описания    могут  быть  опущены  только  в
определениях  внешних  функций  (#10)    или  в  описаниях  внешних
функций. Список  описателей может  быть пустым  только при описании
класса  (#8.5)   или   перечисления   (#8.10),   то   есть,   когда
спецификаторы_описания     -     это     class_спецификатор     или
enum_спецификатор. Описания   имен описываются в #8.8; описания asm
описаны в #8.11.

  спецификатор_описания:
      sc_спецификатор
      спецификатор_типа
      фнк_спецификатор
      friend
      typedef

  спецификаторы_описания:
      спецификатор_описания спецификатор_описания opt

  Список должен  быть внутренне  непротиворечив в  описываемом ниже
смысле.

     8.1 Спецификаторы класса памяти

  Спецификаторы "класса памяти" (sc-спецификатор) это:

  sc-спецификатор:
      auto
      static
      extern
      register

  Описания, использующие  спецификаторы  auto,  static  и  register
также служат  определениями тем,  что они  вызывают  резервирование
соответствующего объема  памяти. Если  описание extern  не является
определением (#4.2),  то где-то  еще должно  быть  определение  для
данных идентификаторов.
  Описание register  лучше  всего  представить  как  описание  auto
(автоматический) с подсказкой компилятору, что описанные переменные
усиленно используются.  Подсказка может быть проигнорирована. К ним
не может применяться операция получения адреса &.
  Спецификаторы  auto  или  register  могут  применяться  только  к
именам, описанным  в блоке,  или к  формальным  параметрам.  Внутри

                             - стр 275 -

блока не может быть описаний ни статических функций, ни статических
формальных параметров.
  В описании может быть задан максимум один sc_спецификатор. Если в
описании отсутсвует  sc_спецификатор, то  класс памяти  принимается
автоматическим  внутри   функции  и  статическим  вне.  Исключение:
функции не могут быть автоматическими.
  Спецификаторы static  и extern  могут использоваться  только  для
имен объектов и функций.
  Некоторые спецификаторы  могут использоваться  только в описаниях
функций:

  фнк-спецификатор:
      overload
      inline
      virtual

  Спецификатор перегрузки  overload делает  возможным использование
одного имени для обозначения нескольких функций; см. #8.9.
  Спецификатор inline  является только  подсказкой компилятору,  не
влияет  на   смысл  программы   и  может  быть  проигнорирован.  Он
используется, чтобы  указать на  то, что при вызове функции inline-
подстановка тела функции предпочтительнее обычной реализацци вызова
функции. Функция  (#8.5.2 и  #8.5.10), определенная внутри описания
класса, является inline по умолчанию.
  Спецификатор virtual  может  использоваться  только  в  описаниях
членов класса; см. #8.5.4.
  Спецификатор friend  используется для отмены правил скрытия имени
для членов  класса и  может использоваться  только внутри  описаний
классов; см. #8.5.9.
  С помощью спецификатора typedef вводится имя для типа; см. #8.8.

     8.2 Спецификаторы Типа

  Спецификаторами типов (спецификатор_типа) являются:

  спецификатор_типа:
      простое_имя_типа
      class_спецификатор
      enum-спецификатор
      сложный_спецификатор_типа
      const

  Слово   const    можно    добавлять    к    любому    допустимому
спецификатору_типа. В  остальных случаях в описании может быть дано
не более  одного спецификатора_типа.  Объект типа const не является
lvalue. Если  в описании  опущен спецификатор  типа, он принимается
int.

                             - стр 276 -

  простое_имя_типа:
      char
      short
      int
      long
      unsigned
      float
      double
      const
      void

  Слова  long,   short   и   unsigned   можно   рассматривать   как
прилагательные. Они  могут применяться  к типу  int; unsigned может
также применяться к типам char, short и long.
  Спецификаторы класса  и перечисления  обсуждаются в  #8.5 и #8.10
соответственно.

  сложный_спецификатор_типа:
      ключ typedef-имя
      ключ идентификатор

  ключ:
      class
      struct
      union
      enum

  Сложный спецификатор  типа можно  использовать для  ссылки на имя
класса или  перечисления там,  где имя  может быть скрыто локальным
именем. Например:

  class x { ... };

  void f(int x)
  {
      class x a;
      // ...
  }

  Если  имя   класса  или   перечисления  ранее  описано  не  было,
сложный_спецификатор_типа работает как описание_имени; см. #8.8.

     8.3 Описатели

  Список_описателей,  появляющийся  в  описании,  есть  разделенная
запятыми последовательность  описателей, каждый  из  которых  может
иметь инициализатор.

  список_описателей:
      иниц_описатель
      иниц_описатель  ,  список_описателей

                             - стр 277 -

  иниц_описатель:
      описатель  инициализатор opt

  Инициализаторы  обсуждаются   в  #8.6.  Спецификатор  в  описании
указывает  тип   и  класс  памяти  объектов,  к  которым  относятся
описатели. Описатели имеют синтаксис:

  описатель:
      оп_имя
      ( описатель )
      * const opt  описатель
      & const opt  описатель
      описатель   ( список_описаний_параметров )
      описатель     [ константное_выражение opt ]

  оп-имя:
      простое_оп_имя
      typedef-имя  ::  простое_оп_имя

  простое_оп_имя:
      идентификатор
      typedef-имя
      ~  typedef-имя
      имя_функции_операции
      имя_функции_преобразования

Группировка та же, что и в выражениях.

     8.4 Смысл описателей

  Каждый  описатель   считается  утверждением   того,  что  если  в
выражении возникает  конструкция,  имеющаяя  ту  же  форму,  что  и
описатель, то  она дает  объект указанного  типа и  класса  памяти.
Каждый  описатель   содержит  ровно  одно  оп_имя;  оно  определяет
описываемый  идентификатор.   За  исключеним   описаний   некоторых
специальных  функций   (см.  #8.5.2)   ,   оп_имя   будет   простым
идентификатором.
  Если  в   качестве  описателя  возникает  ничем  не    снабженный
идентификатор,  то   он  имеет   тип,   указанный   спецификатором,
возглавляющим описание.
  Описатель в  скобках эквивалентен описателю без скобок, но связку
сложных описателей скобки могут изменять.
  Теперь представим себе описание

  T D1

где T  - спецификатор  типа (как  int и  т.д.), а  D1 -  описатель.
Допустим, что  это описание заставляет идентификатор иметь тип "...
T", где  "..." пусто,  если идентификатор  D1  есть  просто  обычый
идентификатор (так  что тип  x в  "int x"  есть просто int). Тогда,
если  D1  имеет вид

  *D

                             - стр 278 -

то тип содержащегося идентификатора есть "... указатель на T."
  Если D1 имеет вид

  * const D

то тип содержащегося идентификатора есть "... константный указатель
на T", то есть, того же типа, что и *D, но не lvalue.
  Если D1 имеет вид

  &D

или

  & const D

то  тип  содержащегося  идентификатора  есть  "...  ссылка  на  T."
Поскольку ссылка по определению не может быть lvalue, использование
Предыдущая страница Следующая страница
1 ... 36 37 38 39 40 41 42  43 44 45 46 47 48 49 50
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (4)

Реклама