Ocenite etot tekst:


---------------------------------------------------------------
 Vtoroe dopolnennoe izdanie
---------------------------------------------------------------





|to spravochnoe rukovodstvo opisyvaet yazyk programmirovaniya S++ po
sostoyanii na maj 1991. S++ - yazyk programmirovaniya obshchego naznacheniya,
baziruyushchijsya na yazyke programmirovaniya S X.

X  "The C Programming Language" B. Kernighan, D. Ritchie. Prentice
   Hall, 1978, 1988.
   Est' russkij perevod: "YAzyk programmirovaniya S. Zadachi po yazyku S"
   B. Kernigan, D. Ritchi, A. F'yuer. "Finansy i statistika". 1984

V dopolnenie k vozmozhnostyam S yazyk S++ predostavlyaet klassy, funkcii
podstanovki, peregruzku operacij, peregruzku imen funkcij, postoyannye
tipy, ssylki, operatory upravleniya svobodnoj pamyat'yu, proverku
parametrov funkcij i privedenie tipov. Vse rasshireniya S summiruyutsya
v $$R.18.1. Razlichiya mezhdu S++ i ANSI C++ privedeny v $$R.18.2 X.

X  American National Standard X3.159-1989. Amerikanskij nacional'nyj
   standart.

Rasshireniya  S++ versii 1985 goda do dannogo opisaniya summiruyutsya v
$$R.18.1.2. Razdely, otnosyashchiesya k shablonam tipa ($$R.14) i
upravleniyu osobymi situaciyami ($$R.15), yavlyayutsya mestami planiruemyh
rasshirenij yazyka.



|to rukovodstvo soderzhit sleduyushchee:
1. Vvedenie.
2. Soglasheniya o leksicheskih ponyatiyah.
3. Osnovnye ponyatiya.
4. Standartnye preobrazovaniya.
5. Vyrazheniya.
6. Operatory.
7. Opisaniya.
8. Opisateli.
9. Klassy.
10. Proizvodnye klassy.
11. Kontrol' dostupa k chlenam.
12. Special'nye funkcii-chleny.
13. Peregruzka.
14. SHablony tipov.
15. Upravlenie osobymi situaciyami.
16. Preprocessornaya obrabotka.
    Prilozhenie A: Svodka sintaksisa
    Prilozhenie B: Sovmestimost'



V zapisi sintaksisa yazyka v etom rukovodstve sintaksicheskie ponyatiya
oboznachayutsya kursivom, a literal'nye slova i simvoly shriftom postoyannoj
shiriny. Varianty perechislyayutsya na otdel'nyh strokah, za isklyucheniem
teh nemnogih sluchaev, kogda dlinnyj spisok variantov daetsya na odnoj
stroke s pometkoj "odin iz". Neobyazatel'nyj terminal'nyj ili
neterminal'nyj simvol oboznachaetsya s pomoshch'yu nizhnego indeksa "opt",
poetomu

   { vyrazhenie opt }

oznachaet neobyazatel'noe vyrazhenie, zaklyuchennoe v figurnye skobki.



Programma na S++ sostoit iz odnogo ili neskol'kih fajlov ($$R.3.3).
S logicheskoj tochki zreniya fajl transliruetsya za neskol'ko prohodov.
Pervyj prohod sostoit v preprocessornoj obrabotke ($$R.16), na kotoroj
proishodit vklyuchenie fajlov i makropodstanovka. Rabota preprocessora
upravlyaetsya s pomoshch'yu komand, yavlyayushchihsya strokami, pervyj simvol
kotoryh otlichnyj ot probela est' # ($$R2.1). Rezul'tat raboty
preprocessora est' posledovatel'nost' leksem. Takuyu posledovatel'nost'
leksem, t.e. fajl posle preprocessornoj obrabotki, nazyvayut
edinicej translyacii.



Sushchestvuyut leksemy pyati vidov: identifikatory, sluzhebnye slova,
literaly, operacii i razlichnye razdeliteli. Probely, vertikal'naya
i gorizontal'naya tabulyaciya, konec stroki, perevod stroki i kommentarii
(vse vmeste "obobshchennye" probely), kak ukazano nizhe, ignoriruyutsya,
za isklyucheniem togo, chto oni otdelyayut leksemy. Obobshchennye probely
nuzhny, chtoby razdelit' stoyashchie ryadom identifikatory, sluzhebnye
slova i konstanty.
   Esli vhodnoj potok razobran na leksemy do dannogo simvola, to
sleduyushchej leksemoj schitaetsya leksema s maksimal'no vozmozhnoj dlinoj,
kotoraya nachinaetsya s etogo simvola.



Kommentarii
Simvoly /* nachinayut kommentarij, kotoryj zavershaetsya simvolami */.
Takie kommentarii ne mogut byt' vlozhennymi. Simvoly // nachinayut
kommentarij, kotoryj zavershaetsya koncom etoj stroki. Simvoly //,
/* i */ ne imeyut special'nogo naznacheniya v kommentarii // i
rassmatrivayutsya kak obychnye simvoly. Analogichno simvoly // i /*
ne imeyut special'nogo naznacheniya vnutri kommentariya /*.



Identifikator - eto posledovatel'nost' bukv i cifr proizvol'noj dliny.
Pervyj simvol dolzhen byt' bukvoj, simvol podcherkivaniya _ schitaetsya
bukvoj. Propisnye i strochnye bukvy razlichayutsya. Vse simvoly
sushchestvenny.



Perechislennye nizhe identifikatory fiksiruyutsya kak sluzhebnye slova i
v drugom smysle ne mogut ispol'zovat'sya:

 asm        continue     float    new          signed      try
 auto       default      for      operator     sizeof      typedef
 break      delete       friend   private      static      union
 case       do           goto     protected    struct      unsigned
 catch      double       if       public       switch      virtual
 char       else         inline   register     template    void
 class      enum         int      return       this        volatile
 const      extern       long     short        throw       while

V dopolnenie k etomu identifikatory, soderzhashchie dvojnoe podcherkivanie
(__) rezerviruyutsya dlya realizacij S++ i standartnyh bibliotek i
pol'zovateli ne dolzhny upotreblyat' ih.
   V predstavlenii programmy na S++ v kodirovke ASCII ispol'zuyutsya
v kachestve operacij ili razdelitelej sleduyushchie simvoly:

  !  %  ^  &   *  (  )  -  +  =  {  }  |  ~
  [  ]  \  ;   '  :  "  <  >  ?   , .  /

a sleduyushchie kombinacii simvolov ispol'zuyutsya dlya zadaniya operacij:

  ->  ++  --  .*  ->*  <<  >>   <=  >=  ==  !=  &&
  ||  *=  /=  %=  +=   -=  <<=  >>= &=  ^=  |=  ::

Kazhdaya operaciya schitaetsya otdel'noj leksemoj.
   V dopolnenii k etomu sleduyushchie simvoly rezerviruyutsya dlya preprocessora:

   #  ##

  Opredelennye, zavisyashchie ot realizacii, svojstva, takie kak
tip operacii sizeof ($$R5.3.2) ili diapazony bazovyh tipov
($$R.3.6.1) opredelyayutsya v standartnyh zagolovochnyh fajlah
($$R.16.4)

      <float.h>   <limits.h>  <stddef.h>

|ti fajly yavlyayutsya chast'yu ANSI standarta dlya S. Krome togo
zagolovochnye fajly

      <new.h>    <stdarg.h>   <stdlib.h>

opredelyayut tipy samyh vazhnyh bibliotechnyh funkcij. Dva poslednih
fajla vhodyat v ANSI standart dlya S, fajl <new.h> otnositsya tol'ko
k S++.



Est' neskol'ko vidov literalov (chasto nazyvaemyh "konstantami").
    literal:
              celaya konstanta
              simvol'naya konstanta
              konstanta s plavayushchej tochkoj
              stroka literalov



Vse celye konstanty, sostoyashchie iz posledovatel'nosti cifr, schitayutsya
desyatichnymi (osnovanie schisleniya desyat'), esli tol'ko oni ne nachinayutsya
s 0 (cifra nol'). Posledovatel'nost' cifr, nachinayushchayasya s 0,
schitaetsya vos'merichnym celym (osnovanie schisleniya vosem'). Cifry 8 i 9
ne yavlyayutsya vos'merichnymi. Posledovatel'nost' cifr, nachinayushchayasya s
0x ili 0X, schitaetsya shestnadcaterichnym celym (osnovanie schisleniya
shestnadcat'). SHestandcaterichnye cifry mogut sostoyat' iz simvolov
ot a ili A do f ili F s desyatichnymi znacheniyami ih ot desyati do
pyatnadcati. Naprimer, chislo dvenadcat' mozhno zapisat' kak 12,
014 ili 0XC.
     Tip celoj konstanty opredelyaetsya ee predstavleniem, znacheniem i
okonchaniem. Esli ona desyatichnaya i ne imeet okonchaniya, ee tip budet
pervym podhodyashchim dlya ee znacheniya iz sleduyushchih tipov: int, long int,
unsigned long int. Esli ona vos'merichnaya ili shestnadcaterichnaya i
ne imeet okonchaniya, ee tip budet pervym podhodyashchim dlya ee znacheniya
iz sleduyushchih: int, unsigned int, long int, unsigned long int.
Esli ona okanchivaetsya simvolom u ili U, ee tip budet pervym podhodyashchim
dlya ee znacheniya iz sleduyushchih: unsigned int, unsigned long int. Esli
ona okanchivaetsya simvolom l ili L, ee tip budet pervym podhodyashchim
dlya ee znacheniya iz sleduyushchih: long int, unsigned long int. Esli
ona okanchivaetsya na ul, lu, uL, Lu, Ul, lU, UL ili LU, ee tipom
budet unsigned long int.



Simvol'noj konstantoj yavlyaetsya odin ili neskol'ko simvolov, zaklyuchennye
v odinochnye kavychki, naprimer 'x'. Konstanta iz odnogo simvola imeet
tip char. Znachenie konstanty iz odnogo simvola est' poryadkovyj nomer
simvola v tablice kodirovki simvolov na dannoj mashine. Simvol'nye
konstanty iz neskol'kih simvolov imeyut tip int. Znachenie takoj
konstanty zavisit ot realizacii.
    Nekotorye simvoly, ne imeyushchie graficheskogo predstavleniya, kak
odinochnaya kavychka ',dvojnaya kavychka ", znak voprosa ?, obratnaya
drobnaya cherta \, mozhno predstavlyat' kombinaciej simvolov (nachinayushchejsya
s \) v sootvetstvii s privodimoj nizhe tablicej:

     konec stroki                  NL (LF)  \n
     gorizontal'naya tabulyaciya      HT       \t
     vertikal'naya tabulyaciya        VT       \v
     shag nazad                     BS       \b
     vozvrat karetki               CR       \r
     perevod formata (avtoregistr) FF       \f
     signal                        BEL      \a
     obratnaya drobnaya cherta        \        \\
     znak voprosa                  ?        \?
     odinochnaya kavychka             '        \'
     dvojnaya kavychka               "        \"
     vos'merichnoe chislo            ooo      \ooo
     shestnadcaterichnoe chislo       hhh      \xhhh

Esli za obratnoj drobnoj chertoj sleduet simvol, otlichnyj ot
perechislennyh, rezul'tat neopredelen.
Kombinaciya \ooo sostoit iz obratnoj drobnoj cherty, a kotoroj
sleduyut odna, dve ili tri vos'merichnye cifry. Schitaetsya, chto oni
opredelyayut znachenie iskomogo simvola. Kombinaciya \xhhh sostoit iz
iz obratnoj drobnoj cherty, za kotoroj sleduet x, a za nim, v svoyu
ochered', sleduet posledovatel'nost' shestnadcaterichnyh cifr.
Schitaetsya, chto ona zadaet znachenie iskomogo simvola. Net ogranicheniya
na dlinu  etoj  posledovatel'nosti shestnadcaterichnyh cifr.
Posledovatel'nost' vos'merichnyh ili shestnadcaterichnyh cifr
okanchivaetsya, kogda vstrechaetsya pervyj simvol, kotoryj ne est'
vos'merichnaya ili shestnadcaterichnaya cifra sootvetstvenno. Esli
znachenie simvol'noj konstanty prevoshodit maksimal'noe iz char,
to ono opredelyaetsya realizaciej.
    Simvol'naya konstanta, kotoroj neposredstvenno predshestvuet
bukva L, yavlyaetsya shirokoj simvol'noj konstantoj, naprimer, L'ab'.
Takie konstanty imeyut tip wchar_t, yavlyayushchijsya celochislennym tipom
($$R.3.6.1), opredelennom v standartnom zagolovochnom fajle
<stddef.h>. SHirokie simvoly prednaznacheny dlya takogo nabora
simvolov, gde znachenie simvola ne pomeshchaetsya v odin bajt.



Konstanty s plavayushchej tochkoj sostoyat iz celoj chasti, simvola
tochka, drobnoj chasti, e ili E, celogo pokazatelya s vozmozhnym
znakom i vozmozhnym okonchaniem, ukazyvayushchim tip. Celaya i drobnaya
chasti sostoyat iz posledovatel'nosti desyatichnyh (osnovanie
schisleniya desyat') cifr. Ili celaya chast', ili drobnaya chast'
(no ne obe) mogut otsutstvovat'. Ili tochka, ili simvol e (ili E)
vmeste s pokazatelem mogut otsutstvovat' (no ne oba). Tip
konstanty s plavayushchej tochkoj est' double, esli tol'ko on ne
zadan yavno s pomoshch'yu okonchaniya. Okonchaniya f ili F zadayut tip
float, okonchaniya l ili L zadayut tip long double.



Stroka literalov est' posledovatel'nost' simvolov  (kak oni opredeleny
v $$R.2.5.2), zaklyuchennaya v dvojnye kavychki, t.e. "...". Stroka
imeet tip "massiv simvolov" i klass pamyati static ($$R.3.5), ona
inicializiruetsya zadannymi simvolami. Budut li vse stroki razlichny
(t.e. hranitsya v otdel'nyh ob容ktah), opredelyaetsya realizaciej.
    Sosednie stroki literalov konkateniruyutsya. Simvoly v strokah,
poluchennyh pri konkatenacii, hranyatsya otdel'no. Naprimer, posle
konkatenacii

    "\xA"  "B"

stroka budet soderzhat' dva simvola '\xA' i 'B' (a ne odin
shestnadcaterichnyj simvol '\xAB').
     Posle vseh neobhodimyh konkatenacij k stroke dobavlyaetsya
simvol '\0', chtoby programma, chitayushchaya stroku, mogla opredelit'
ee konec. Razmer stroki raven chislu vseh ee simvolov, vklyuchaya
simvol zavershitel' stroki. Vnutri stroki pered simvolom dvojnoj
kavychki " dolzhen idti simvol \.
    Stroka literalov, pered kotoroj neposredstvenno idet simvol L,
schitaetsya shirokosimvol'noj strokoj, naprimer, L"asdf". Takaya
stroka imeet tip "massiv elementov tipa wchar_t", gde wchar_t
celochislennyj tip, opredelennyj v standartnom zagolovochnom fajle
<stddef.h>. Rezul'tat konkatenacii obychnyh i shirokosimvol'nyh
strok literalov neopredelen.



Imya oboznachaet ob容kt, funkciyu, mnozhestvo funkcij, element
perechisleniya, tip, chlen klassa, shablon tipa, znachenie ili metku.
Imya stanovitsya izvestno v programme s pomoshch'yu opisaniya. Imya mozhno
ispol'zovat' tol'ko v predelah chasti programmy, nazyvaemoj oblast'yu
vidimosti imeni. Imya imeet tip, kotoryj zadaet ego ispol'zovanie.
Imya, ispol'zuemoe v bolee chem odnoj edinice translyacii, mozhet
oboznachat' odin i tot zhe (a mozhet i raznye) ob容kt, funkciyu, tip,
shablon tipa ili znachenie, v zavisimosti ot komponovki ($$R.3.3)
etih edinic translyacii.
    Ob容kt imeet oblast' dlya ego hraneniya ($$R.3.7). Poimenovannyj
ob容kt imeet klass pamyati ($$R.3.5), kotoryj opredelyaet ego vremya
zhizni. Interpretaciya znachenij, hranyashchihsya v ob容kte, opredelyaetsya
tipom vyrazheniya, zadayushchego dostup k ob容ktu.



Opisanie ($$r.7) delaet izvestnym v programme odno ili neskol'ko
imen. Opisanie schitaetsya opredeleniem, esli tol'ko ono ne opisyvaet
funkciyu bez zadaniya ee tela ($$R.8.3), ne soderzhit opisatelya
extern ($$R.7.11), ne imeet chasti inicializacii ili tela funkcii,
ne yavlyaetsya opisaniem staticheskogo chlena dannyh v opisanii klassa
($$R.9.4), ne yavlyaetsya opisaniem imeni klassa ($$R.9.1), ne yavlyaetsya
opisaniem typedef ($$R.7.1.3). Nizhe privedeny primery opredelenij:

     int a;
     extern const c = 1;
     int f(int x) { return x+a; }
     struct S { int a; int b; };
     enum { up, down };

togda kak nizhe sleduyut tol'ko opisaniya:

     extern int a;
     extern const c;
     int f(int);
     struct S;
     typedef int Int;

   Dlya kazhdogo ob容kta, funkcii, klassa i elementa perechisleniya,
ispol'zuemyh v programme, dolzhno byt' tol'ko odno opredelenie
($$R.3.3). Esli funkciya nikogda ne vyzyvaetsya i ee adres nikogda
ne ispol'zuetsya, ee ne nuzhno opredelyat'. Analogichno, esli imya klassa
ispol'zuetsya tol'ko tak, chto ne trebuetsya znat' opredeleniya klassa,
to takoj klass ne nado opredelyat'.



Sushchestvuet chetyre oblasti vidimosti: lokal'naya, funkciya, fajl i klass.
    Lokal'naya: Imya, opisannoe v bloke ($$R.6.3), yavlyaetsya lokal'nym
    v etom bloke i mozhet ispol'zovat'sya tol'ko v nem i v blokah,
    soderzhashchihsya v etom bloke i poyavlyayushchihsya posle momenta opisaniya.
    Imena formal'nyh parametrov rassmatrivayutsya, kak esli by oni byli
    opisany v samom ob容mlyushchem bloke etoj funkcii.
    Funkciya: Metki ($$R.6.1) mozhno ispol'zovat' povsyudu v funkcii,
    v kotoroj oni opisany. Tol'ko metki imeyut oblast' vidimosti,
    sovpadayushchuyu s funkciej.
    Fajl: Imya opisannoe vne vseh blokov ($$R.6.3) i klassov ($$R.9)
    imeet oblast' vidimosti fajl i mozhet byt' ispol'zovano v edinice
    translyacii, v kotoroj ono poyavlyaetsya posle momenta opisaniya. Imena,
    opisannye s fajlovoj oblast'yu vidimosti, nazyvayutsya global'nymi.
    Klass: Imya chlena klassa yavlyaetsya lokal'nym v svoem klasse i
    ono mozhet byt' ispol'zovano tol'ko v funkcii-chlene etogo klassa
    ($$R.9.3), ili posle operacii . , primenyaemoj k ob容ktu dannogo
    klassa ($$R.5.2.4) ili ob容ktu proizvodnogo  klassa($$R.10),
    ili posle operacii ->, primenyaemoj k ukazatelyu na ob容kt dannogo
    klassa ($$R.5.2.4) ili na ob容kt proizvodnogo klassa, ili posle
    operacii razresheniya :: ($$R.5.1), primenennoj k imeni dannogo
    ili proizvodnogo klassa. Imya, vvedennoe s pomoshch'yu operacii
   friend ($$R.11.4), prinadlezhit toj zhe oblasti opredelennosti,
   chto i klass, soderzhashchij opisanie friend. Klass, vpervye
   opisannyj v operatore return ili v tipe parametra, prinadlezhit
   k global'noj oblasti vidimosti.
Special'nye soglasheniya dejstvuyut na imena, vvedennye pri opisanii
parametrov funkcii ($$R.8.2.5) i v opisaniyah friend ($$R.11.4).
     Imya mozhet byt' skryto yavnym opisaniem togo zhe imeni v ob容mlyushchem
bloke ili klasse. Skrytoe imya chlena klassa vse-taki mozhno
ispol'zovat', esli ono predvaryaetsya imenem klassa, k kotoromu
primenena operaciya :: ($$R.4.1, $$R.9.4, $$R.10). Skrytoe imya ob容kta,
funkcii, tipa ili elementa perechisleniya s fajlovoj oblast'yu vidimosti
mozhno ispol'zovat', esli ono predvaryaetsya unarnoj operaciej ::
($$R.5.1). V dopolnenii k etomu, imya klassa ($$R.9.1) mozhet byt'
skryto imenem ob容kta, funkcii ili elementa perechisleniya, imeyushchego
tu zhe oblast' vidimosti. Esli klass i ob容kt, ili funkciya, ili
element perechisleniya opisany (v lyubom poryadke) s odinakovym imenem
v odnoj oblasti vidimosti, to imya klassa stanovitsya skrytym. Imya
klassa, skrytoe v lokal'noj oblasti vidimosti ili v oblasti
vidimosti klassa imenem ob容kta, funkcii ili elementa perechisleniya,
vse-taki mozhno ispol'zovat', esli predvarit' ego podhodyashchej
specifikaciej class, struct ili union ($$R.7.1.6). Analogichno,
skrytoe imya elementa perechisleniya mozhno ispol'zovat', esli
predvarit' ego specifikaciej tipa enum ($$R.7.1.6). V $$R.10.4
privoditsya svodka pravil oblasti vidimosti.
Momentom opisaniya imeni schitaetsya moment zaversheniya opisatelya imeni
($$R.8), predshestvuyushchej chasti inicializacii (esli ona est').
Naprimer,

    int x = 12;
    { int x = x; }

Zdes' vtoroe x inicializiruetsya svoim sobstvennym (neopredelennym)
znacheniem.
   Momentom opisaniya elementa perechisleniya schitaetsya moment srazu
posle poyavleniya ego identifikatora, naprimer:

    enum { x = x };

Zdes' element perechisleniya x opyat' inicializiruetsya svoim sobstvennym
(neopredelennym) znacheniem.



Programma sostoit iz odnogo ili neskol'kih fajlov, svyazyvaemyh vmeste
($$R.2). Fajl sostoit iz posledovatel'nosti opisanij.
    Imya s fajlovoj oblast'yu vidimosti, kotoroe yavno opisano kak
static, yavlyaetsya lokal'nym v svoej edinice translyacii i mozhet
ispol'zovat'sya dlya imenovaniya ob容ktov, funkcij i t.p. v drugih
edinicah translyacii. Govoryat, chto takie imena imeyut vnutrennee
svyazyvanie. Imya s fajlovoj oblast'yu vidimosti, kotoroe yavno opisano
so specifikaciej inline, yavlyaetsya lokal'nym v svoej edinice
translyacii. Imya s fajlovoj oblast'yu vidimosti, kotoroe yavno opisano
so specifikaciej const i ne opisano yavno kak extern, schitaetsya
lokal'nym v svoej edinice translyacii. To zhe verno dlya imeni klassa,
kotoroe ne ispol'zovalos' v nelokal'nyh dlya dannoj edinicy
translyacii opisaniyah ob容kta, funkcii  ili klassa, i kotoryj ne
imeet staticheskih chlenov ($$R.9.4), ne imeet funkcij-chlenov, krome
podstanovok ($$R.9.3.2). Vsyakoe opisanie nekotorogo imeni s
fajlovoj oblast'yu vidimosti, kotoroe ne opisano odnim iz perechislennyh
sposobov tak, chtoby imet' vnutrennee svyazyvanie, v mnogofajlovoj
programme oboznachaet odin i tot zhe ob容kt ($$R.3.7), funkciyu
($$R.8.2.5) ili klass ($$R.9). Takie imena nazyvayutsya vneshnimi ili
govoryat, chto oni imeyut vneshnee svyazyvanie. V chastnosti, poskol'ku
nel'zya opisat' imya klassa kak static, vsyakoe upotreblenie imeni
nekotorogo klassa s fajlovoj oblast'yu vidimosti, kotoryj (klass)
ispol'zovalsya dlya opisaniya ob容kta ili funkcii s vneshnim svyazyvaniem,
ili zhe kotoryj imeet staticheskij chlen ili funkciyu-chlen,
ne yavlyayushchuyusya podstanovkoj, budet oboznachat' odin i tot zhe klass.
   Imena opredelyaemyh tipov (typedef $$R.7.13), elementy perechisleniya
($$R.7.2) ili imena shablonov tipa ($$R.14) ne imeyut vneshnego
svyazyvaniya.
   Staticheskie chleny klassa ($$R.9.4) dopuskayut vneshnee svyazyvanie.
   Funkcii-chleny, ne yavlyayushchiesya podstanovkoj, dopuskayut vneshnee
svyazyvanie. Funkcii-chleny, yavlyayushchiesya podstanovkoj, dolzhny imet'
v tochnosti odno opredelenie v programme.
   Lokal'nye imena ($$R.3.2), yavno opisannye so specifikaciej
extern, imeyut vneshnee svyazyvanie, esli tol'ko oni uzhe ne byli
opisany kak static ($$R.7.1.1).
   Tipy, ispol'zuemye vo vseh opisaniyah nekotorogo vneshnego imeni,
dolzhny sovpadat', za isklyucheniem ispol'zovaniya imen opredelyaemyh
tipov ($$R.7.1.3) i ukazaniya granic massivov ($$R.8.2.4).
Dolzhno byt' v tochnosti odno opredelenie dlya kazhdoj funkcii, ob容kta,
klassa i elementa perechisleniya, ispol'zuemyh v programme. Odnako,
esli funkciya nikogda ne vyzyvaetsya i ee adres nikogda ne ispol'zuetsya,
ee ne nuzhno opredelyat'. Analogichno, esli imya klassa ispol'zuetsya
tol'ko takim obrazom, chto ne trebuetsya znat' opredelenie klassa,
to klass ne nuzhno opredelyat'.
   Oblast' vidimosti funkcii mozhet byt' tol'ko fajl ili klass.
   S pomoshch'yu specifikacii svyazyvaniya mozhno dobit'sya svyazyvaniya s
opisaniyami na drugom yazyke ($$R.7.4).



Programma dolzhna soderzhat' funkciyu s imenem main(). Ej pripisyvaetsya
rol' nachala programmy. |ta funkciya ne yavlyaetsya predopredelennoj
dlya translyatora, ona ne mozhet byt' peregruzhena, a ee tip zavisit
ot realizacii. Predpolagaetsya, chto lyubaya realizaciya dolzhna
dopuskat' dva privedennyh nizhe opredeleniya i chto mozhno dobavlyat'
posle argv lyubye parametry. Funkciya main mozhet opredelyat'sya tak

   int main() { /* ... */ }

ili

   int main(int argc, char* argv[]) { /* ... */ }

V poslednem opredelenii argc zadaet chislo parametrov, peredavaemyh
programme okruzheniem, v kotorom ona vypolnyaetsya. Esli argc ne
ravno nulyu, parametry dolzhny peredavat'sya kak stroki, zavershayushchiesya
simvolom '\0', s pomoshch'yu argv[0] do argv[argc-1], prichem
argv[0] dolzhno byt' imenem, pod kotorym programma byla zapushchena,
ili "". Dolzhno garantirovat'sya, chto argv[argc]==0.
    Funkciya main() ne dolzhna vyzyvat'sya v programme. Svyazyvanie
main() ($$R.3.3) zavisit ot realizacii. Nel'zya poluchat' adres
main() i ne sleduet opisyvat' ee kak inline ili static.
Vyzov funkcii

    void exit(int);

opisannoj v <stdlib.h>, zavershaet programmu. Znachenie parametra
peredaetsya okruzheniyu programmy v kachestve rezul'tata programmy.
    Inicializaciya nelokal'nyh staticheskih ob容ktov ($$R.3.5)
edinicy translyacii proishodit prezhde pervogo obrashcheniya k funkcii
ili ob容ktu, opredelennomu v etoj edinice translyacii. |ta
inicializaciya ($$R.8.4, $$R.9.4, &&R.12.1, $$R.12.6.1) mozhet
byt' provedena pered vypolneniem pervogo operatora main() ili
otlozhena do lyubogo momenta, predshestvuyushchego pervomu ispol'zovaniyu
funkcii ili ob容kta, opredelennyh v dannoj edinice translyacii.
Vse staticheskie ob容kty po umolchaniyu inicializiruyutsya nulem ($$R.8.4)
prezhde lyuboj dinamicheskoj (vo vremeni vypolneniya programmy)
inicializacii. Bol'she nikakih trebovanij na poryadok inicializacii
ob容ktov iz razlichnyh edinic translyacii ne nalagaetsya. Inicializaciya
lokal'nyh i staticheskih ob容ktov opisana v $$R.8.4.
     Destruktory ($$R.12.4) dlya inicializirovannyh staticheskih
ob容ktov vyzyvayutsya pri vozvrate iz main() ili pri vyzove exit().
Unichtozhenie proishodit v obratnom poryadke po sravneniyu s
inicializaciej. S pomoshch'yu funkcii atexit() iz <stdlib.h> mozhno
ukazat' funkciyu, kotoruyu nuzhno vyzyvat' pri vyhode iz programmy.
Esli bylo obrashchenie k funkcii atexit(), ob容kty, inicializirovannye
do vyzova atexit(), ne dolzhny unichtozhat'sya do teh por, poka ne
proizojdet vyzov funkcii, ukazannoj v atexit(). Esli realizaciya S++
sosushchestvuet s realizaciej S, vse dejstviya, kotorye dolzhny byli
proizojti posle vyzova funkcii, zadannoj v atexit(), proishodyat
tol'ko posle vyzova vseh destruktorov.
    Vyzov funkcii

    void abort();

opisannoj v <stdlib.h>, zavershaet programmu bez vypolneniya
destruktorov staticheskih ob容ktov i bez vyzova funkcij, zadannyh
v atexit().



Sushchestvuet dva opisyvaemyh klassa pamyati: avtomaticheskij i staticheskij.
   Avtomaticheskie ob容kty stanovyatsya lokal'nymi pri peredache
upravleniya v kazhdyj blok.
   Staticheskie ob容kty sushchestvuyut i sohranyayut svoe znachenie vo vse
vremya vypolneniya programmy.
   Avtomaticheskie ob容kty inicializiruyutsya ($$R.12.1) vsyakij raz,
kogda upravlenie perehodit v blok, gde oni opredeleny i unichtozhayutsya
($$R.12.4) po vyhode iz etogo bloka ($$R.6.7).
   Poimenovannyj avtomaticheskij ob容kt ne dolzhen byt' unichtozhen
do okonchaniya ego bloka, tochno tak zhe, kak ne mozhet byt' isklyuchen
poimenovannyj avtomaticheskij ob容kt klassa, imeyushchego konstruktor
ili destruktor s pobochnym effektom, dazhe esli kazhetsya, chto etot
ob容kt ne ispol'zuetsya.
   Analogichno, global'nyj ob容kt klassa s konstruktorom ili
destruktorom, imeyushchimi pobochnyj effekt, ne mozhet byt' isklyuchen,
dazhe esli kazhetsya, chto on ne ispol'zuetsya.
  Staticheskie ob容kty inicializiruyutsya i unichtozhayutsya v
sootvetstvii s opisaniem v $$R.3.4 i $$R.6.7. S nekotorymi ob容ktami
ne svyazano nikakogo imeni, sm. $$R.5.3.3 i $$R.12.2. Vse global'nye
ob容kty imeyut klass pamyati staticheskij. Lokal'nym ob容ktam i chlenam
klassa mozhno predat' klass pamyati staticheskij s pomoshch'yu yavnogo
ispol'zovaniya specifikacii klassa pamyati static ($$R.7.1.1).



Sushchestvuyut dva vida tipov: osnovnye i proizvodnye.



Sushchestvuet neskol'ko osnovnyh tipov. V standartnom zagolovochnom
fajle <limits.h> zadayutsya v zavisimosti ot realizacii minimal'nye i
maksimal'nye znacheniya kazhdogo tipa.
   Ob容kty, opisannye kak simvoly (char), mogut hranit' lyuboj
element iz bazovogo nabora simvolov dannoj mashiny. Esli simvol
etogo nabora hranitsya v simvol'noj peremennoj, to ee znachenie
ravno celomu znacheniyu koda etogo simvola. Simvoly mogut yavno
opisyvat'sya kak unsigned ili signed. Obychnyj char, signed char i
unsigned char yavlyayutsya tremya razlichnymi tipami. Dlya vseh etih
treh tipov trebuetsya odinakovyj ob容m pamyati.
   S pomoshch'yu opisanij short int, int i long int mozhno opredelit'
celye treh razlichnyh razmerov. Dlya dlinnyh celyh trebuetsya pamyati
ne men'she chem dlya korotkih celyh, no v realizacii ili korotkie
celye, ili dlinnye celye, ili i te i drugie mogut okazat'sya
ekvivalentnymi obychnym celym. Obychnye celye imeyut razmer,
opredelyaemyj sistemoj komand, razmery drugih celyh opredelyayutsya
konkretnymi potrebnostyami.
   Dlya kazhdogo iz tipov signed char, short, int i long sushchestvuet
sootvetstvuyushchij bezznakovyj tip, kotoryj zanimaet tot zhe ob容m
pamyati i udovletvoryaet tem zhe trebovaniyam vyravnivaniya.
Trebovanie vyravnivanie - eto ogranichenie na znachenie ukazatelya
na dannyj ob容kt, kotoroe nakladyvaet realizaciya ($$R.5.4).
   Bezznakovye celye, opisannye kak unsigned, podchinyayutsya zakonom
arifmetiki po modulyu 2@n, gde n chislo bitov, ispol'zuemoe dlya
predstavleniya znacheniya. Otsyuda sleduet, chto v arifmetike bezznakovyh
ne voznikaet perepolneniya.
  Sushchestvuet tri tipa s plavayushchej tochkoj: float, double i long double.
Tip double garantiruet ne men'shuyu tochnost' predstavleniya, chem
float, a tip long double garantiruet tochnost' ne men'she, chem u
double. Harakteristiki osnovnyh tipov s plavayushchej tochkoj opredelyayutsya
v sootvetstvii s realizaciej v standartnom zagolovochnom fajle
<float.h>.
    Tipy char, int lyubyh razmerov i tip perechisleniya ($$R.7.2)
nazyvayutsya celochislennymi tipami. Celochislennye tipy vmeste s
tipami s plavayushchej tochkoj obrazuyut arifmeticheskie tipy.
   Tip void zadaet pustoe mnozhestvo znachenij. On ispol'zuetsya dlya
oboznacheniya tipa funkcij, kotorye ne vozvrashchayut rezul'tat. Nel'zya
opisyvat' ob容kty s tipom void. Lyuboe vyrazhenie mozhno yavno
preobrazovat' k tipu void ($$R.5.4), poluchivsheesya vyrazhenie mozhno
ispol'zovat' tol'ko kak vyrazhenie-operator ($$R.6.2), kak
levyj operand operacii zapyataya ($$R.5.18) ili v kachestve vtorogo ili
tret'ego operanda v operacii ?: ($$R.5.16).



Sushchestvuet potencial'no beskonechnoe chislo proizvodnyh tipov, kotorye
stroyatsya iz osnovnyh tipov sleduyushchimi sposobami:
    massiv ob容ktov dannogo tipa, $$R.8.4;
    funkcii, imeyushchie parametry dannogo tipa i vozvrashchayushchie ob容kty
    dannogo tipa, $$R.8.2.5;
    ukazateli na ob容kty ili funkcii dannogo tipa, $$R.8.2.1;
    ssylki na ob容kty ili funkcii dannogo tipa, $$R.8.2.2;
    konstanty, yavlyayushchiesya znacheniyami dannogo tipa, $$R.7.1.6;
    klassy, soderzhashchie sovokupnost' ob容ktov razlichnyh tipov ($$R.9),
    nabor funkcij dlya upravleniya etimi ob容ktami ($$R.9.3) i
    i spisok ogranichenij na dostup k etim ob容ktam i funkciyam, $$R.11;
    struktury, kotorye yavlyayutsya klassami bez standartnyh ogranichenij
    na dostup, $$r.11;
    ob容dineniya, kotorye yavlyayutsya strukturami, sposobnymi soderzhat'
    v raznoe vremya ob容kty razlichnyh tipov, $$R.9.5;
    ukazateli na chleny klassov, kotorye zadayut chleny dannogo tipa
    sredi vseh ob容ktov dannogo klassa, $$R.8.2.3.
V obshchem sluchae ukazannye metody postroeniya ob容ktov mogut primenyat'sya
rekursivno, ogranicheniya privedeny v $$r.8.2.1, $$R.8.2.4, $$R.8.2.5
i $$R.8.2.2.
  Pro ukazatel' na ob容kty tipa T govoryat "ukazatel' na na T". Naprimer,
pro ukazatel' na ob容kt tipa int govoryat "ukazatel' na int", a
ukazatel' na ob容kt klassa X nazyvaetsya "ukazatel' na X".
  Ob容kty tipa void* (ukazatel' na void), const void* i
volatile void* mogut ispol'zovat'sya kak ukazateli na ob容kty
neizvestnogo tipa. Ob容kt tipa void* dolzhen imet' dostatochno pamyati,
chtoby hranit' ukazatel' na lyuboj ob容kt.
  Vse fragmenty rukovodstva, govoryashchie ob "ukazatelyah", ne otnosyatsya
k ukazatelyam na chleny, za isklyucheniem ukazatelej na staticheskie
chleny.



Osnovnye i proizvodnye tipy mozhno poimenovat' s pomoshch'yu mehanizma
typedef ($$R.7.1.3), a semejstvo tipov i funkcij mozhno zadat' i
poimenovat' s pomoshch'yu mehanizma shablona tipov ($$R.14).



Lyuboj ob容kt - eto nekotoraya oblast' pamyati, adres - vyrazhenie,
ssylayushcheesya na ob容kt ili funkciyu. Ochevidnym primerom adresa budet
imya ob容kta. Sushchestvuyut operacii, porozhdayushchie adresa, naprimer,
esli E vyrazhenie tipa ukazatel', to *E - adresnoe vyrazhenie,
sootvetstvuyushchee ob容ktu, na kotoryj ukazyvaet E. Termin "adres"
("lvalue" t.e. left value - levaya velichina) poyavlyaetsya iz operatora
prisvaivaniya E1 = E2, gde levyj operand E1 dolzhen "adresovat'"
izmenyaemuyu peremennuyu. Pri obsuzhdenii vseh operacij v $$R.5 ukazyvaetsya
primenimy li oni k adresnym operandam i porozhdayut li oni sami adresa.
Adres mozhet izmenyat'sya, esli on ne yavlyaetsya imenem funkcii,
imenem massiva ili const.



Nekotorye operacii v zavisimosti ot svoih operandov mogut vyzvat'
preobrazovanie znacheniya operanda ot odnogo tipa k drugomu. Zdes'
opisyvayutsya preobrazovaniya, vyzvannye samymi obychnymi operaciyami,
i ob座asnyaetsya kakovy mogut byt' rezul'taty takih preobrazovanij.
Po mere nadobnosti budut dany dopolnitel'nye ob座asneniya pri
obsuzhdenii kazhdoj operacii. Podobnye preobrazovaniya takzhe proishodyat
pri inicializacii ($$R.8.4, $$R.8.4.3, $$R.12.8, $$R.12.1).
V $$R.12.3  i $$R.13.2 opisyvayutsya preobrazovaniya, zadannye
pol'zovatelem, i ih sootnosheniya so standartnymi preobrazovaniyami.
V rezul'tate preobrazovaniya mozhet poluchit'sya adres, tol'ko esli
rezul'tat est' ssylka ($$R.8.2.2).



Vsyudu, gde trebuetsya celoe, mozhno ispol'zovat' char, short int,
element perechisleniya ($$R.7.2) ili bitovoe pole ($$R.9.6), prichem
v znakovom i bezznakovom variantah. Esli int mozhet predstavlyat'
vse znacheniya ishodnogo tipa, znachenie preobrazuetsya k int, inache
ono preobrazuetsya k unsigned int. |to nazyvaetsya standartnym
preobrazovaniem dlya celochislennyh.



Esli celoe preobrazuetsya v bezznakovyj tip, to poluchennoe znachenie
est' naimen'shee bezznakovoe celoe, sovpadayushchee s celym so znakom
po (mod 2**n), gde n est' chislo bitov v predstavlenii bezznakovogo
celogo. Dlya predstavleniya v dopolnitel'nom kode eto preobrazovanie
lish' konceptual'noe, nikakih izmenenij v dvoichnom predstavlenii
v dejstvitel'nosti ne proishodit.\
    Esli celoe preobrazuetsya k znakovomu tipu, znachenie ne menyaetsya,
pri uslovii, chto ego mozhno predstavit' s pomoshch'yu novogo tipa,
inache znachenie opredelyaetsya realizaciej.



Dlya vyrazhenij tipa float mozhet ispol'zovat'sya arifmetika s obychnoj
tochnost'yu. Esli znachenie s plavayushchej tochkoj men'shej tochnosti
preobrazuetsya v znachenie tipa float ravnoj ili bol'shej tochnosti,
to izmeneniya znacheniya ne proishodit. Esli znachenie s plavayushchej
tochkoj bol'shej tochnosti preobrazuetsya v znachenie tipa float
men'shej tochnosti i znachenie nahoditsya v predelah, zadavaemyh
predstavleniem tipa, to v rezul'tate mozhet poluchit'sya ili
blizhajshee bol'shee ili blizhajshee men'shee predstavimoe znachenie.
Esli rezul'tat okazalsya vne granic predstavleniya tipa, povedenie
neopredeleno.



Preobrazovanie znacheniya s plavayushchej tochkoj k celochislennomu tipu
svoditsya k "usecheniyu", t.e. otbrasyvaniyu drobnoj chasti. Takie
preobrazovaniya zavisyat ot mashiny, v chastnosti v kakuyu storonu budet
prohodit' usechenie dlya otricatel'nyh chisel opredelyaetsya na raznyh
mashinah po raznomu. Rezul'tat schitaetsya neopredelennym, esli
znachenie nel'zya predstavit' v celochislennom tipe.
    Preobrazovaniya celochislennyh znachenij k znacheniyam s plavayushchej
tochkoj matematicheski korrektny nastol'ko, naskol'ko eto pozvolyaet
sistema komand. Mozhet proizojti poterya tochnosti, esli celochislennoe
znachenie nel'zya tochno predstavit' kak znachenie s plavayushchej tochkoj.


  R.4.5 Arifmeticheskie preobrazovaniya

Dlya bol'shinstva operacij preobrazovaniya operandov i tip rezul'tata
opredelyayutsya odnimi i i temi zhe pravilami. |to pravilo mozhno nazvat'
"obychnymi arifmeticheskimi preobrazovaniyami".
   Esli odin iz operandov est' long double, drugoj operand
   preobrazuetsya v long double.
   Inache, esli odin iz operandov est' double, drugoj operand
   preobrazuetsya v double.
   Inache, esli odin iz operandov est' float, drugoj operand
   preobrazuetsya v float.
   Inache, esli standartnye celochislennye preobrazovaniya ($$R.4.1)
   proishodyat nad oboimi operandami.
   Togda, esli odin iz operandov est' unsigned long, drugoj
   operand preobrazuetsya v unsigned long.
   Inache, esli odin iz operandov est' long int, a drugoj -
   unsigned int, to pri uslovii, chto long int mozhet predstavlyat'
   vse vozmozhnye znacheniya unsigned int, znachenie unsigned int
   preobrazuetsya v long int, v protivnom sluchae oba operanda
   preobrazuyutsya v unsigned long int.
   Inache, esli odin iz operandov est' long, drugoj operand
   preobrazuetsya v long.
   Inache, esli odin iz operandov est' unsigned, drugoj operand
   preobrazuetsya v unsigned.
   Inache, oba operanda dolzhny byt' int.



Vsyudu, gde ukazateli ($$R.8.2.1) prisvaivayutsya, inicializiruyutsya,
sravnivayutsya ili ispol'zuyutsya inym obrazom, mogut proishodit'
sleduyushchie preobrazovaniya:
   Konstantnoe vyrazhenie ($$R.5.19), kotoroe svoditsya k nulyu,
   preobrazuetsya v ukazatel', obychno nazyvaemyj pustym ukazatelem.
   Garantiruetsya, chto znachenie takogo ukazatelya budet otlichno ot
   lyubogo ukazatelya na ob容kt ili funkciyu.
   Ukazatel' na ob容kt lyubogo tipa, ne yavlyayushchegosya const ili
   volatile, mozhno preobrazovat' v void*.
   Ukazatel' na funkciyu mozhno preobrazovat' v void*, pri uslovii,
   chto dlya void* otvoditsya dostatochno pamyati, chtoby hranit' etot
   ukazatel'.
   Ukazatel' na dannyj klass mozhno preobrazovat' v ukazatel' na
   dostupnyj bazovyj klass dannogo klassa ($$R.10), esli takoe
   preobrazovanie ne soderzhit dvusmyslennost' ($$R.10.1). Bazovyj
   klass schitaetsya dostupnym, esli dostupny ego obshchie chleny ($$R.11.1).
   Rezul'tatom preobrazovaniya budet ukazatel' na ob容kt tipa bazovogo
   klassa, vlozhennyj v ob容kt tipa proizvodnogo klassa. Pustoj ukazatel'
   (0) preobrazuetsya sam v sebya.
   Vyrazhenie tipa "massiv T" mozhet preobrazovyvat'sya v ukazatel'
   na nachal'nyj element massiva.
   Vyrazhenie tipa "funkciya, vozvrashchayushchaya T" preobrazuetsya v "ukazatel'
   na funkciyu, vozvrashchayushchuyu T", za isklyucheniem teh sluchaev, kogda
   ono ispol'zuetsya kak operand adresnoj operacii & ili operacii
   vyzova funkcii ().



Vsyudu, gde ssylki ($$R.8.2.2) inicializiruyutsya (vklyuchaya peredachu
parametrov ($$R.5.2.2) i vozvrat znacheniya funkcii ($$R.6.6.3)) ili
ispol'zuyutsya inym obrazom, vozmozhny sleduyushchie preobrazovaniya:
   Ssylka na dannyj klass mozhet byt' preobrazovana v ssylku na dostupnyj
   bazovyj klass ($$R.10, $$R.11.1) dannogo klassa ($$R.8.4.3),
   pri uslovii, chto takoe preobrazovanie ne soderzhit dvusmyslennosti
   ($$R.10.1.1). Rezul'tatom preobrazovaniya budet ssylka na ob容kt
   bazovogo klassa, vlozhennyj v ob容kt proizvodnogo klassa.



Vsyudu, gde ukazateli na chleny ($$R.8.2.3) inicializiruyutsya,
prisvaivayutsya, sravnivayutsya ili ispol'zuyutsya inym obrazom,
mogut proishodit' sleduyushchie preobrazovaniya:
   Konstantnoe vyrazhenie ($$R.5.19), kotoroe svoditsya k nulyu,
   preobrazuetsya v ukazatel' na chlen. Garantiruetsya, chto ego
   znachenie budet otlichno ot lyubyh drugih ukazatelej na chleny.
   Ukazatel' na chlen dannogo klassa mozhno preobrazovat' v
   ukazatel' na chlen proizvodnogo ot dannogo klassa, pri uslovii,
   chto dopustimo obratnoe preobrazovanie ot ukazatelya na chlen proizvodnogo
   klassa v ukazatel' chlen bazovogo klassa, i chto ono vypolnimo
   odnoznachnym obrazom ($$R.10.1.1).
   Pravilo preobrazovaniya ukazatelej na chleny (t.e. ot ukazatelya na
chlen bazovogo klassa k ukazatelyu na chlen proizvodnogo klassa) vyglyadit
perevernutym, esli sravnivat' ego s pravilom dlya ukazatelej na
ob容kty (t.e. ot ukazatelya na proizvodnyj ob容kt k ukazatelyu na
bazovyj ob容kt) ($$R.4.6, $$R.10). |to neobhodimo dlya garantii
nadezhnosti tipov.
   Otmetim, chto ukazatel' na chlen ne yavlyaetsya ukazatelem na ob容kt
ili ukazatelem na funkciyu i pravila preobrazovanij takih ukazatelej
ne primenimy dlya ukazatelej na chleny. V chastnosti ukazatel' na chlen
nel'zya preobrazovat' v void*.



Zdes' opredelyayutsya sintaksis, poryadok vychisleniya i naznachenie
vyrazhenij. Vyrazhenie - eto posledovatel'nost' operacij i operandov,
kotoraya zadaet vychislenie. Vychislenie mozhet vydavat' v kachestve
rezul'tata znachenie i mozhet vyzyvat' pobochnye effekty.
   Operacii mogut byt' peregruzheny, t.e. im mozhet byt' pripisano znachenie,
kogda oni primenyayutsya k vyrazheniyam tipa klass ($$R.9). Primenenie
peregruzhennyh operacij preobrazuetsya v vyzovy funkcij v sootvetstvii
s opisaniem v $$R.13.4. Peregruzhennye operacii podchinyayutsya
sintaksicheskim pravilam, opredelennym v etom razdele, no trebovaniya
k tipu operanda, adresu i poryadku vychisleniya zamenyayutsya na pravila
vyzova funkcii. Sootnosheniya mezhdu operaciyami, tipa ++a oznachaet
a+=1, ne garantiruyutsya dlya peregruzhennyh operacij ($$R.13.4).
   V etom razdele opisano primenenie operacij k tipam, dlya kotoryh
oni ne yavlyayutsya peregruzhennymi. Peregruzka operacij ne mozhet izmenit'
pravila primeneniya operacij k tipam, dlya kotoryh takoe primenenie
predusmotreno v samom yazyke.
   Poryadok vychisleniya podvyrazhenij opredelyaetsya prioritetom i poryadkom
primeneniya operacij. Obychnye matematicheskie pravila associativnosti
i kommutativnosti operacij dejstvuyut tol'ko, esli operacii
dejstvitel'no associativny ili kommutativny. Za isklyucheniem
ogovorennyh sluchaev poryadok vychisleniya operandov konkretnoj operacii
neopredelen. V chastnosti, esli v vyrazhenii znachenie izmenyaetsya
dvazhdy, rezul'tat vyrazheniya neopredelen, esli tol'ko poryadok
vypolneniya ne obespechivaetsya samimi operaciyami, naprimer:

    i = v[i++];  // the value of `i' is undefined
    i=7,i++,i++; // `i' becomes 9

   Reakciya na perepolnenie i delenie na nul' pri vychislenii vyrazheniya
zavisit ot realizacii. V bol'shinstve sushchestvuyushchih realizacij S++
ignoriruetsya perepolnenie celyh. Reakciya na delenie na nul' i
oshibki operacij nad chislami s plavayushchej tochkoj var'iruetsya ot
mashiny k mashine i obychno svyazana s sootvetstvuyushchimi bibliotechnymi
funkciyami.
   Krome ogovorennyh sluchaev, operandy tipa const T, volatile T,
T&, const T& i volatile T& mozhno ispol'zovat', kak esli by oni
imeli tip prosto T. Analogichno, operandy tipa T* const, T*volatile
mozhno ispol'zovat', kak esli by oni imeli tip prosto T*, za
isklyucheniem ogovorennyh sluchaev. Analogichno, prosto tip T mozhno
ispol'zovat' vsyudu, gde trebuetsya tip volatile T ili const T.
|ti pravila mozhet primenyat' v kombinacii, tak chto const T* volatile
mozhno ispol'zovat' tam, gde trebuetsya T*, za isklyucheniem ogovorennyh
sluchaev. Pri rassmotrenii razresheniya peregruzki ($$R.13.2) takoe
ispol'zovanie operacij ne schitaetsya standartnym preobrazovaniem
operandov.
    Esli vyrazhenie imeet tip "ssylka na T" ($$R.8.2.2, $$R.8.4.3),
znachenie vyrazhenie est' ob容kt tipa "T", na kotoryj nastroena
ssylka. Vyrazhenie yavlyaetsya adresom. Ssylku mozhno predstavlyat' kak
imya ob容kta.
    Dopustimy opredelennye pol'zovatelem preobrazovaniya ob容ktov
klassa v (i obratno) osnovnye tipy, ukazateli i t.d. ($$R.12.3)
Esli oni nedvusmyslenny ($$R.13.2), takie preobrazovaniya mogut
primenyat'sya translyatorom vsegda, kogda poyavlyaetsya ob容kt tipa klassa
v kachestve operanda operacii, v kachestve inicializiruyushchego
vyrazheniya ($$R.8.4), v kachestve vyrazheniya, zadayushchego uslovie ($$R.6.4),
ili v kachestve vyrazheniya, ispol'zuemogo v operatore cikla ($$R.6.5),
ili v kachestve znacheniya, vozvrashchaemogo funkciej ($$R.6.6.3),
ili v kachestve parametra funkcii ($$R.5.2.2).



Pervichnymi vyrazheniyami yavlyayutsya literaly, imena i imena, opredelennye
s pomoshch'yu operacii razresheniya oblasti vidimosti ::.

     pervichnoe-vyrazhenie:
          literal
          this
          :: identifikator
          :: imya-funkcii-operacii
          :: utochnennoe-imya
          ( vyrazhenie )
          imya

   Literal yavlyaetsya pervichnym vyrazheniem. Ego tip opredelyaetsya
ego vidom ($$R.2.5).
   V tele nestaticheskoj funkcii-chlene ($$R.9.3) sluzhebnoe slovo
this oboznachaet ukazatel' na ob容kt, k kotoromu otnositsya vyzov
funkcii. Sluzhebnoe slovo this nel'zya ispol'zovat' vne tela
funkcii-chlena klassa.
   Operaciya :: , za kotoroj sleduet identifikator ili
imya-operacii-funkcii ili utochnennoe-imya yavlyayutsya pervichnym
vyrazheniem. Ego tip zadaetsya opisaniem identifikatora, imeni
ili imeni-funkcii-operacii. Rezul'tatom yavlyaetsya identifikator,
imya ili imya-funkcii-operacii. Rezul'tat yavlyaetsya adresom, esli
identifikator yavlyaetsya adresom. Identifikator ili imya-funkcii-operacii
dolzhny imet' fajlovuyu oblast' vidimosti. S pomoshch'yu operacii ::
mozhno obrashchat'sya k tipu, ob容ktu, funkcii ili elementu perechisleniya,
dazhe esli oboznachayushchij ih identifikator yavlyaetsya skrytym ($$R.3.2).
   Vyrazhenie v skobkah yavlyaetsya pervichnym vyrazheniem, tip i znachenie
kotorogo identichny im zhe u vyrazheniya bez skobok. Nalichie skobok
ne vliyaet na to, yavlyaetsya vyrazhenie adresom ili net.
   Ponyatie imya - eto opredelennoe pervichnoe-vyrazhenie, kotoroe
mozhet poyavlyat'sya tol'ko posle . i -> ($$R.5.2.4):

     imya:
        identifikator
        imya-funkcii-operacii
        imya-funkcii-preobrazovaniya
        ~imya-klassa
        utochnennoe-imya

  Identifikator est' imya, pri uslovii chto on opisan nadlezhashchim obrazom
($$R.7). Ponyatie imya-funkcii-operacii opisano v ($$R.13.4), a
ponyatie imya-funkcii-preobrazovaniya v ($$R.12.3.2). Konstrukciya
~imya-klassa oboznachaet destruktor ($$R.12.4).

       utochnennoe-imya:
                utochnyayushchee-imya-klassa :: imya

Ponyatie utochnyayushchee-imya-klassa, za kotorym sleduet :: i imya chlena
etogo klassa ($$R.9.2), ili chlena bazovogo po otnosheniyu k dannomu
klassa ($$R.10) yavlyaetsya utochnennoe-imya. Ego tip est'
tip chlena, a rezul'tat vyrazheniya est' etot chlen. Rezul'tat yavlyaetsya
adresom, esli takovym yavlyaetsya chlen. Imya klassa mozhet byt' skryto
drugim imenem (ne tipa), v takom sluchae vse ravno imya klassa
dostupno i ego mozhno ispol'zovat'. Esli ispol'zuetsya
imya-klassa::imya-klassa ili imya-klassa::~imya-klassa, oba ponyatiya
imya-klassa dolzhny oboznachat' odin i tot zhe klass. S pomoshch'yu takoj
zapisi oboznachayutsya konstruktory ($$R.12.1) i destruktory ($$R.12.4)
sootvetstvenno. Mozhno ispol'zovat' utochnyayushchie imena
neodnokratno, naprimer, N1::N2::N3::n, chtoby oboznachat' vlozhennye
tipy ($$R.9.7).



   Postfiksnye vyrazheniya primenyayutsya sleva napravo.
      postfiksnoe-vyrazhenie:
             pervichnoe-vyrazhenie
             postfiksnoe-vyrazhenie [ vyrazhenie ]
             postfiksnoe-vyrazhenie ( spisok-vyrazhenij opt )
             imya-prostogo-tipa     ( spisok-vyrazhenij opt )
             postfiksnoe-vyrazhenie .  imya
             postfiksnoe-vyrazhenie -> imya
             postfiksnoe-vyrazhenie ++
             postfiksnoe-vyrazhenie --
      spisok-vyrazhenij:
            vyrazhenie-prisvaivaniya
            spisok-vyrazhenij , vyrazhenie-prisvaivaniya



Postfiksnoe vyrazhenie, za kotorym sleduet vyrazhenie v kvadratnyh
skobkah, yavlyaetsya postfiksnym vyrazheniem. Intuitivnyj smysl ego
indeksirovanie. Pervoe iz vyrazhenij dolzhno imet' tip "ukazatel' na T",
a vtoroe byt' celochislennogo tipa. Tip rezul'tata est' "T". Vyrazhenie
E1[E2] sovpadaet (po opredeleniyu) s vyrazheniem *((E1) + (E2)).
Podrobnosti operacij * i + dany v $$R.5.3  i $$R.5.7, a massivy
obsuzhdayutsya v $$R.8.2.4.



Vyzov funkcii yavlyaetsya postfiksnym vyrazheniem, za kotorym sleduet,
vozmozhno pustoj, spisok vyrazhenij v skobkah, razdelennyh zapyatoj.
|ti vyrazheniya obrazuyut fakticheskie parametry funkcii. Postfiksnoe
vyrazhenie dolzhno imet' tip "funkciya, vozvrashchayushchaya T", "ukazatel' na
funkciyu, vozvrashchayushchuyu T" ili "ssylka na funkciyu, vozvrashchayushchuyu T",
a rezul'tat operacii vyzova imeet tip "T".
    Pri vyzove funkcii proishodit inicializaciya kazhdogo formal'nogo
parametra ($$R.8.4.3, $$R.12.8, $$r.12.1) fakticheskim parametrom.
Proizvodyatsya standartnye ($$R.4) i zadannye pol'zovatelem ($$R.12.3)
preobrazovaniya tipa. V funkcii mozhet izmenyat'sya znacheniya nepostoyannyh
formal'nyh parametrov, no eti izmeneniya ne mogut povliyat' na znacheniya
fakticheskih parametrov, krome togo sluchaya, kogda formal'nyj parametr
imeet tip ssylki bez specifikacii const ($$R.8.2.2). Esli formal'nyj
parametr imeet tip ssylki pri neobhodimosti mozhet sozdavat'sya
vremennaya peremennaya ($$R.7.1.6, $$R.2.5,$$R.2.5.4,$$R.8.2.4,
$$R.12.2). Dobavim, chto vozmozhno izmenenie nepostoyannyh ob容ktov s
pomoshch'yu parametrov-ukazatelej.
   Funkciyu mozhno opisat' takim obrazom, chto ona smozhet ispol'zovat'
men'shee chislo parametrov (opredeliv parametry po umolchaniyu $$R.8.2.6)
ili bol'shee chislo parametrov (s pomoshch'yu ellipsisa ... $$R.8.2.5),
chem bylo ukazano pri opredelenii funkcii ($$R.8.3).
   Funkciyu mozhno vyzvat' tol'ko, esli opisanie ee dostupno v toj oblasti
vidimosti, gde proishodit vyzov. Otsyuda sleduet, vsyakij formal'nyj
parametr, sootvetstvuyushchij nekotoromu fakticheskomu parametru, dolzhen
byt' dostupen, esli ne schitat' ellipsis (...).
    Pered vyzovom vsyakij fakticheskij parametr tipa float, dlya kotorogo
net formal'nogo parametra, preobrazuetsya k tipu double,  a tipa
char, short, perechisleniya ili bitovoe pole, dlya kotorogo net
formal'nogo parametra, preobrazuetsya k tipu int ili unsigned
soglasno standartnym preobrazovaniyam celochislennyh ($$R.4.1).
Ob容kt, yavlyayushchijsya klassom i ne imeyushchij opisaniya formal'nogo parametra,
peredaetsya pri vyzove kak struktura dannyh.
    Ob容kt, yavlyayushchijsya klassom i imeyushchij opisanie formal'nogo
parametra peredaetsya s pomoshch'yu inicializacii formal'nogo parametra
fakticheskim parametrom, kotoraya proishodit pered vypolneniem
funkcii posredstvom vyzova konstruktora ($$R.12.2, $$R.12.8).
    Poryadok vychislenij parametrov neopredelen i uchtite, chto on
mozhet byt' razlichen u raznyh translyatorov. Vse pobochnye effekty
vyrazhenij fakticheskih parametrov mogut proishodit' pered nachalom
vypolneniya funkcii. Poryadok vychisleniya postfiksnyh vyrazhenij i
spiska vyrazhenij parametrov neopredelen.
    Dopustimy rekursivnye vyzovy.
    Operaciya vyzova funkcii porozhdaet adres tol'ko, esli tip
rezul'tata est' adres.



Konstrukciya imya-prostogo-tipa ($$R.7.1.6), za kotoroj sleduet
spisok-vyrazhenij v skobkah obrazuet znachenie ukazannogo tipa
s uchetom spiska vyrazhenij. Esli spisok vyrazhenij soderzhit bolee
odnogo znacheniya, tip dolzhen byt' klassom s konstruktorom, opisannym
sootvetstvuyushchim obrazom ($$R.8.4, $$R.12.1).
   Konstrukciya imya-prostogo-tipa ($$R.7.1.6), za kotoroj sleduet
para skobok (pustaya), obrazuet znachenie ukazannogo tipa. Esli tip
yavlyaetsya klassom s konstruktorom, opisannym sootvetstvuyushchim obrazom,
budet vyzvan etot konstruktor, v protivnom sluchae rezul'tatom
budet neopredelennoe znachenie ukazannogo tipa, sm. tak zhe ($$R.5.4).



Postfiksnoe vyrazhenie, za kotorym sleduet tochka (.) i imya, yavlyaetsya
postfiksnym vyrazheniem. Pervoe vyrazhenie dolzhno byt' ob容ktom tipa
klass, a imya dolzhno byt' imenem chlena etogo klassa. Rezul'tatom budet
poimenovannyj chlen ob容kta i on budet adresom, esli chlen yavlyaetsya
adresom.
   Postfiksnoe vyrazhenie, za kotorym sleduet strelka (->)  i imya,
yavlyaetsya postfiksnym vyrazheniem. Pervoe vyrazhenie dolzhno byt'
ukazatelem na ob容kt tipa klass, a imya dolzhno byt' imenem chlena
etogo klassa. Rezul'tatom budet poimenovannyj chlen ob容kta, na
kotoryj nastroen ukazatel' i on budet adresom, esli chlen yavlyaetsya
adresom. Znachit vyrazhenie E1->MOS tozhe samoe, chto (*E1).MOS.
   Obratite vnimanie, chto "ob容kty tipa klass" mogut byt'
strukturami ($$R.9.2) ili ob容dineniyami ($$R.9.5). Klassy obsuzhdayutsya
v $$R.9.



Znachenie, poluchaemoe v rezul'tate primeneniya postfiksnoj operacii ++,
est' znachenie operanda. Operand dolzhen byt' izmenyaemym adresom.
Tip operanda dolzhen byt' arifmeticheskij ili tip ukazatelya. Posle
vyborki rezul'tata (dlya dal'nejshego ispol'zovaniya) ob容kt uvelichivaetsya
na 1. Tip rezul'tata sovpadaet s tipom operanda, no ne yavlyaetsya
adresom (sm. tak zhe $$R.5.7 i $$R.5.17).
   Postfiksnaya operaciya -- svoditsya k operacii dekrementa (umen'shenie
na 1) i analogichna operacii ++.



Vyrazheniya s unarnymi operaciyami vypolnyayutsya sprava nalevo.

    unarnoe-vyrazhenie:
         postfiksnoe-vyrazhenie
         ++ unarnoe vyrazhenie
         -- unarnoe vyrazhenie
         unarnaya-operaciya vyrazhenie-privedeniya
         sizeof unarnaya-operaciya
         sizeof ( imya-tipa )
         vyrazhenie-razmeshcheniya
         vyrazhenie-osvobozhdeniya
     unarnaya-operaciya: odin iz
          *  &  +  -  !  ~

Unarnaya operaciya * oznachaet kosvennost': vyrazhenie dolzhno byt'
ukazatelem, a rezul'tat yavlyaetsya adresom, ssylayushchimsya na ob容kt, na
kotoryj ukazyvaet vyrazhenie. Esli tip vyrazheniya est' "ukazatel' na T",
to tip rezul'tata budet "T".
   Rezul'tatom unarnoj operacii & budet ukazatel' na ee operand.
Operand dolzhen byt' funkciej ili adresom ili konstrukciej
utochnennoe-imya. Dlya pervyh dvuh sluchaev, esli tip vyrazheniya
est' "T", to tip rezul'tata budet "ukazatel' na T". V chastnosti,
adres ob容kta tipa const T imeet tip const T*, tozhe verno dlya
volatile. Dlya sluchaya utochnennoe imya esli chlen klassa "C" ne yavlyaetsya
staticheskim i imeet tip "T", to tip rezul'tata operacii budet
"ukazatel' na chlen C tipa T". Dlya staticheskih chlenov tipa T
rezul'tatom budet obychnyj "ukazatel' na T". Adres peregruzhennoj
funkcii ($$R.13) mozhno brat' tol'ko pri inicializacii ili
prisvaivanii, v kotorom levaya chast' odnoznachno opredelyaet kakaya
versiya peregruzhennoj funkcii imeetsya vvidu ($R13.3).
    Operand unarnoj operacii + dolzhen byt' arifmeticheskogo tipa
ili tipa ukazatel' i rezul'tatom budet znachenie operanda. Dlya
celochislennyh operandov  proizvoditsya standartnoe preobrazovanie
celochislennyh. Tip rezul'tata est' tip preobrazovannogo operanda.
    Operand unarnoj operacii - dolzhen imet' arifmeticheskij tip i
rezul'tatom budet izmenenie znaka operanda. Dlya celochislennyh
operandov vypolnyaetsya standartnoe preobrazovanie celochislennyh.
Operaciya dlya bezznakovyh velichin vypolnyaetsya s pomoshch'yu vychitaniya
znacheniya operanda iz 2**n, gde n chislo bitov v predstavlenii
preobrazovannogo operanda. Tip rezul'tata est' preobrazovannogo
operanda.
    Operand operacii logicheskogo otricaniya ! dolzhen imet'
arifmeticheskij tip ili byt' ukazatelem, rezul'tat raven 1, esli
znachenie operanda est' 0, i raven 0, esli operand ne raven 0.
Tip rezul'tata est' int.
   Operand operacii ~ dolzhen imet' celochislennyj tip, rezul'tatom
budet obrashchenie dvoichnogo predstavleniya operanda. Vypolnyayutsya
standartnye preobrazovaniya celochislennyh. Tip rezul'tata est'
tip preobrazovannogo operanda.



Operand prefiksnoj operacii ++ uvelichivaetsya na 1. Operand dolzhen
byt' izmenyaemym adresom. Tip operanda dolzhen byt' arifmeticheskim
ili ukazatelem. Rezul'tatom yavlyaetsya novoe znachenie operanda,
ono schitaetsya adresom. Vyrazhenie ++x ekvivalentno x+=1. Dlya
utochneniya preobrazovanij mozhno obratit'sya k opisaniyu slozheniya
($$R.5.7) i operacij prisvaivaniya ($$R.5.17).
    Prefiksnaya operaciya -- svoditsya k umen'sheniyu na 1 i vypolnyaetsya
analogichno prefiksnoj operacii ++.



Operaciya sizeof vychislyaet razmer svoego operanda v bajtah. Operand
dolzhen byt' ili vyrazheniem, kotoroe ne vychislyaetsya, ili imenem tipa
v skobkah. Operaciyu sizeof nel'zya primenyat' k funkcii, bitovomu polyu,
neopredelennomu klassu, tipu void ili k massivu s neukazannymi
granicami indeksov. Bajt nikak ne opredelyaetsya yazykom, krome kak
rezul'tata operacii sizeof, imenno sizeof(char) est' 1.
   Esli operaciya primenyaetsya k ssylke, rezul'tatom budet razmer
ob容kta, na kotoryj nastroena ssylka. Esli ona primenyaetsya k klassu,
rezul'tatom budet razmer ob容kta etogo klassa v bajtah s uchetom
vseh dopolnitel'nyh bajtov, kotorye potrebuetsya dlya razmeshcheniya
takogo ob容kta v massive. Razmer lyubogo klassa ili ob容kta klassa
bol'she nulya. V sluchae massiva operaciya vydaet polnoe chislo bajtov
v massive. Otsyuda sleduet, chto razmer massiva iz n elementov raven
razmeru elementa, umnozhennomu na n.
   Operaciya sizeof mozhet primenyat'sya k ukazatelyu na funkciyu, no ne
k samoj funkcii.
   Rezul'tatom operacii budet konstanta tipa size_t. |tot tip
opredelen v standartnom zagolovochnom fajle <stddef.h> i yavlyaetsya
zavisyashchim ot realizacii bezznakovym celochislennym tipom.



Operaciya new prednaznachena dlya sozdaniya ob容kta tipa imya-tipa
($$R.8.1). |tot tip dolzhen byt' tipom ob容kta i funkcii nel'zya
razmeshchat' s ee pomoshch'yu, hotya ukazateli na funkcii mozhno.

     vyrazhenie-razmeshcheniya:
          ::opt new parametry-new opt imya-tipa-new inicializator-new
          ::opt new parametry-new opt ( imya-tipa ) inicializator-new
     parametry-new:
          ( spisok-vyrazhenij )
     imya-tipa-new:
          spisok-specifikacij-tipa opisatel'-new opt
     opisatel'-new:
          * spisok-specifikacij-cv opt opisatel'-new opt
          imya-klassa :: spisok-specifikacij-cv opt opisatel'-new opt
          opisatel'-new opt [ vyrazhenie ]
     inicializator-new:
          ( spisok-inicializatorov opt )

Vremya zhizni ob容kta, sozdannogo s pomoshch'yu new, ne ogranichivaetsya
oblast'yu vidimosti, v kotoroj on byl sozdan. Operaciya new vozvrashchaet
ukazatel' na sozdannyj ob容kt. Esli ob容kt yavlyaetsya massivom,
vozvrashchaetsya ukazatel' na nachal'nyj element massiva. Naprimer,
obe operacii new int i new int[1] vozvratyat int* , a tipom
new int[i][10] budet int(*)[10]. Esli opisyvaetsya tip massiva
($$R.8.2.4), vse razmernosti, krome pervoj, dolzhny byt' vyrazheniyami-
konstantami ($$R.5.19) s polozhitel'nym znacheniem. Pervaya razmernost'
massiva mozhet zadavat'sya proizvol'nym vyrazheniem, dazhe esli
ispol'zuetsya imya-tipa (zdes' narushaetsya obshchee trebovanie, chtoby
razmernosti massiva v konstrukcii imya-tipa byli
vyrazheniyami-konstantami ($$R.5.19)).
   Dopuskaetsya, chtoby vyzyvalas' funkciya operator new() s parametrom
nul'. V takom sluchae vozvrashchaetsya ukazatel' na ob容kt. Pri povtorenii
takih vyzovov budut vozvrashchat'sya ukazateli na raznye ob容kty.
  Konstrukciya spisok-specifikacij-tipa ne dolzhna soderzhat' const,
volatile, opisanie klassa ili perechisleniya.
  Dlya rezervirovaniya pamyati operaciya new obrashchaetsya k funkcii
operator new() ($$R.12.5). Pri razmeshchenii ob容kta tipa T ej v
kachestve pervogo parametra peredaetsya sizeof(T). Konstrukciya
parametry-new ispol'zuetsya dlya peredachi dopolnitel'nyh parametrov.
Naprimer, operaciya new T privodit k vyzovu operator new(sizeof(T)),
a operaciya new(2,f) T  privodit k vyzovu operator new(sizeof(T),2,f).
     Konstrukciya parametry-new mozhet ispol'zovat'sya tol'ko, esli
opisana funkciya operator new() s parametrami sootvetstvuyushchih tipov.
     Esli s pomoshch'yu operacii new sozdaetsya ob容kt ne tipa klass
(v tom chisle i massiv ob容ktov tipa klass), to vyzyvaetsya global'naya
funkciya ::operator new(). Esli s pomoshch'yu new sozdaetsya ob容kt klassa
T, vyzyvaetsya funkciya T::operator new(), esli ona sushchestvuet
(ispol'zuya obychnye pravila prosmotra pri poiske chlenov klassa i ego
bazovyh klassov, $$R.10.1.1), inache vyzyvaetsya global'naya funkciya
::operator new(). Ispol'zovanie operacii ::new() garantiruet, chto
budet vyzyvat'sya global'naya funkciya ::operator new(), dazhe esli
sushchestvuet T::operator new().
    Konstrukciya vyrazhenie-razmeshcheniya mozhet soderzhat' inicializator-new.
Dlya ob容ktov klassov s konstruktorami ($$R.12.1) zadavaemyj eyu
spisok parametrov budet ispol'zovat'sya pri vyzove konstruktora, v
drugih sluchayah konstrukciya inicializator-new dolzhna imet' vid
( vyrazhenie ) ili ( ). Esli vyrazhenie prisutstvuet, ono ispol'zuetsya
dlya inicializacii ob容kta, esli ego net, ob容kt nachnet sushchestvovanie
s neopredelennym znacheniem.\
    Esli klass imeet konstruktor, ob容kt etogo klassa mozhno sozdat'
s pomoshch'yu new tol'ko pri uslovii, chto zadany podhodyashchie parametry,
ili, chto klass imeet standartnyj konstruktor ($$R.12.1).
Otvodit li pamyat' pri sozdanii ob容kta tipa klass sama funkciya
operator new, ili ostavlyaet eto na konstruktor, zavisit ot realizacii.
Kak dlya konstruktora, tak i dlya funkcii operator new() provoditsya
proverka vozmozhnosti dostupa i odnoznachnosti ($$R.12).
   Dlya massivov nel'zya zadavat' inicializatory. Massivy ob容ktov
tipa klassa s konstruktorom mozhno sozdavat' s pomoshch'yu operacii new
tol'ko, esli konstruktor klassa yavlyaetsya standartnym ($$R.12.1).
V etom sluchae standartnyj konstruktor budet vyzyvat'sya dlya kazhdogo
elementa massiva.
   Inicializaciya proizvoditsya tol'ko v tom sluchae, kogda funkciya
operator new() vozvrashchaet nenul'. Esli ona vozvrashchaet 0 (pustoj
ukazatel'), znachenie vyrazheniya est' 0.
   Poryadok vychisleniya vyrazheniya vyzova operator new() dlya polucheniya
pamyati i poryadok vychisleniya parametrov konstruktora neopredelen.
Tak zhe neopredeleno vychislyayutsya li parametry konstruktora, esli
funkciya operator new() vozvratila 0.
   V konstrukcii imya-tipa-new skobki ispol'zovat' neobyazatel'no.
Togda obrashchenie

    new int (*[10])();   // error

mozhet privesti k oshibke, t.k. operacii primenyayutsya v takom poryadke

    (new int) (*[10])(); // error

Ob容kty slozhnogo tipa mozhno zadat' v operacii new s pomoshch'yu yavno
ukazannyh skobok, naprimer, obrashchenie

    new (int (*[10])());

razmeshchaet massiv iz 10 ukazatelej na funkcii (ne imeyushchie parametrov
i vozvrashchayushchie int).
    Konstrukcii imya-tipa-new v vyrazhenie-razmeshcheniya dolzhna byt'
samoj dlinnoj iz vozmozhnyh posledovatel'nostej konstrukcij
opisatel'-new. |to predotvrashchaet kollizii mezhdu operaciyami iz
opisatelej &, *, [] i ih dvojnikami iz vyrazheniya, naprimer,

     new int* i;   // syntax error: parsed as `(new int*) i'
                   //               not s `(new int)*i'

Simvol * ispol'zuetsya v opisatele ukazatelya, a ne v kachestve
operacii umnozheniya.



Operaciya delete unichtozhaet ob容kt, sozdannyj s pomoshch'yu new.

       vyrazhenie-osvobozhdeniya:
          ::opt delete vyrazhenie-privedeniya
          ::opt delete [] vyrazhenie-privedeniya

Rezul'tat imeet tip void. Operandom delete dolzhen byt' ukazatel',
kotoryj vozvrashchaet new. |ffekt primeneniya operacii delete k ukazatelyu,
kotoryj ne poluchen v rezul'tate operacii new bez zadaniya
parametry-new, schitaetsya neopredelennym i obychno privodit k opasnym
posledstviyam. Odnako garantiruetsya, chto udalenie po ukazatelyu s
nulevym znacheniem bezopasno.
    Rezul'tat popytki dostupa k udalennomu ob容ktu neopredelen, a
udalenie ob容kta mozhet izmenit' ego znachenie. Bolee togo, esli
vyrazhenie, zadayushchee ob容kt, yavlyaetsya izmenyaemym adresom, ego
znachenie posle udaleniya neopredeleno.
    Nel'zya udalyat' ukazatel' na konstantu.
    Operaciya delete vyzyvaet destruktor (esli on est' $$12.4)
dlya ob容kta, na kotoryj nastroen ee operand.
    Dlya osvobozhdeniya pamyati, otvedennoj pod ukazyvaemyj ob容kt,
operaciya delete vyzyvaet funkciyu operator delete ($$R.12.5).
Dlya ob容ktov, ne imeyushchih tip klass (v tom chisle i dlya massivov
klassov), ispol'zuetsya global'naya funkciya ::operator delete().
Dlya ob容kta tipa klass T vyzyvaetsya funkciya T::operator delete(),
esli ona est' (ispol'zuya obychnye pravila prosmotra pri poiske
chlenov klassa i proizvodnyh ot nego klassov, $$R.10.1.1), v
protivnom sluchae vyzyvaetsya global'naya funkciya ::operator delete().
Obrashchenie ::delete garantiruet, chto budet vyzyvat'sya global'naya
funkciya ::operator delete(), dazhe esli sushchestvuet T::operator delete().
Dlya udaleniya massivov ispol'zuetsya obrashchenie vida

      delete [ ] vyrazhenie-privedeniya

Zdes' vyrazhenie dolzhno ukazyvat' na massiv. Esli est' destruktory,
oni budut vyzyvat'sya dlya udaleniya ukazannyh ob容ktov.
    Rezul'tat udaleniya massiva s pomoshch'yu prostogo obrashcheniya delete
neopredelen, tak zhe kak i udalenie odinochnogo ob容kta s pomoshch'yu
delete [].



YAvnoe preobrazovanie tipa mozhno zadat' s pomoshch'yu funkcional'noj
zapisi ($$R.5.2.3) ili s pomoshch'yu operacii privedeniya.

       vyrazhenie-privedeniya:
           unarnoe-vyrazhenie
           ( imya-tipa ) vyrazhenie-privedeniya

Zadanie s pomoshch'yu operacii privedeniya ispol'zuetsya dlya oboznacheniya
preobrazovaniya k tipu, kotoryj ne yavlyaetsya konstrukciej
imya-prostogo-tipa.
    V operacii privedeniya nel'zya opredelyat' tipy.
    Vsyakoe preobrazovanie tipa, ne upomyanutoe zdes' i ne yavlyayushcheesya
preobrazovaniem yavno opredelennym pol'zovatelem ($$R.12.3), schitaetsya
oshibkoj.
    Lyuboj tip, kotoryj mozhno preobrazovat' v drugoj s pomoshch'yu
standartnogo preobrazovaniya ($$R.4), mozhno takzhe preobrazovat'
s pomoshch'yu yavnogo preobrazovaniya (privedeniya) i smysl preobrazovaniya
budet tot zhe.
    Ukazatel' mozhno preobrazovat' k lyubomu celochislennomu tipu,
dostatochno bol'shomu, chtoby vmestit' znachenie ukazatelya. Algoritm
preobrazovaniya zavisit ot realizacii, no predpolagaetsya, chto on
budet estestvennym dlya togo, kto znaet sistemu adresacii, ispol'zuemoj
mashiny.
    Znachenie celochislennogo tipa mozhet byt' yavno preobrazovano v
ukazatel'. Ukazatel', preobrazovannyj v celoe dostatochnogo razmera
(esli takie est' v realizacii), i preobrazovannyj obratno k tipu
ukazatelya, dolzhen imet' svoe pervonachal'noe znachenie. Vse drugie
detali perevoda ukazatelya v celoe i obratno zavisyat ot realizacii.
    Ukazatel' na ob容kt odnogo tipa mozhet byt' preobrazovan v
ukazatel' na ob容kt drugogo tipa (s soblyudeniem ogranichenij, ukazannyh
zdes'). Ispol'zovanie poluchivshegosya ukazatelya mozhet vyzvat'
osobuyu adresnuyu situaciyu ("nevernyj adres"), esli preobrazuemyj
ukazatel' ne
nastroen na ob容kt, pravil'nym obrazom vyravnennyj v pamyati.
Garantiruetsya, chto ukazatel' na ob容kt dannogo razmera mozhno
preobrazovat' v ukazatel' na ob容kt ravnogo ili men'shego razmera
i provesti obratnoe preobrazovanie bez izmeneniya znacheniya ukazatelya.
Na razlichnyh mashinah dvoichnoe predstavlenie ukazatelej mozhet byt'
razlichno kak i trebovaniya na vyravnivaniya ob容ktov. Sostavnye
ob容kty vyravnivayutsya po samoj strogoj granice, trebuemoj ih
sostavlyayushchimi. Ukazatel' tipa void* schitaetsya sovmestimym s
ukazatelem na ob容kt lyubogo tipa.
    Ukazatel' na klass B mozhno preobrazovat' v ukazatel' na klass D,
dlya kotorogo klass B yavlyaetsya pryamo ili oposredovanno bazovym
klassom, esli sushchestvuet odnoznachnoe preobrazovanie iz D v B
($$R.4.6, $$.R10.1.1) i esli B yavlyaetsya virtual'nym bazovym klassom
($$R.10.1). Takoe privedenie ot bazovogo klassa k proizvodnomu
klassu predpolagaet, chto ob容kt bazovogo klassa yavlyaetsya vlozhennym
po otnosheniyu k ob容ktu proizvodnogo klassa. V rezul'tate poluchitsya
ukazatel', nastroennyj na ob容mlyushchij ob容kt proizvodnogo klassa.
Esli ob容kt bazovogo klassa ne soderzhitsya ni v kakom ob容kte
proizvodnogo klassa, takaya operaciya privedeniya mozhet vyzvat'
osobuyu situaciyu.
    Pustoj ukazatel' (0) preobrazuetsya sam v sebya.
    Poka eshche neopredelennyj klass mozhno ispol'zovat' v operacii
privedeniya ukazatelya, v etom sluchae nikakih dopushchenij o strukture
klassa ne delaetsya ($$R.10.1).
    Lyuboj ob容kt mozhno yavno preobrazovat' k tipu ssylki X&, esli
ukazatel' na etot ob容kt mozhno yavno preobrazovat' v tip X*.
V rezul'tate privedeniya k ssylke ne proishodit vyzovov konstruktorov
ili funkcij preobrazovanij. Preobrazovanie ssylki na bazovyj klass
v ssylku na proizvodnyj klass rassmatrivaetsya analogichno
preobrazovaniyu ukazatelya na bazovyj klass v ukazatel' na
proizvodnyj klass, uchityvaya voprosy odnoznachnosti, virtual'nyh
klassov i t.d.
    Rezul'tatom privedeniya k ssylke yavlyaetsya adres, v otlichie ot vseh
ostal'nyh privedenij. Rezul'tat privedeniya ukazatelya ili ssylki
nastroen na tot zhe ob容kt, chto i ishodnoe vyrazhenie bez operacii
privedeniya.
   Ukazatel' na funkciyu mozhno yavno preobrazovat' v ukazatel' na
nekotoryj ob容kt pri uslovii, chto tip ukazatelya na etot ob容kt
dostatochno velik, chtoby hranit' ukazatel' na funkciyu. Ukazatel'
na nekotoryj ob容kt mozhno yavno preobrazovat' v ukazatel' na funkciyu
pri uslovii, chto tip ukazatelya na funkciyu dostatochno velik, chtoby
hranit' ukazatel' na etot ob容kt. V oboih sluchayah, ispol'zovanie
ukazatelya, poluchivshegosya v rezul'tate preobrazovaniya, mozhet
vyzvat' osobuyu adresnuyu situaciyu, ili chto-nibud' pohuzhe,
esli ishodnyj ukazatel' ne nastroen na sootvetstvuyushchij ob容kt.
   Ukazatel' na funkciyu odnogo tipa mozhno yavno preobrazovat' v
ukazatel' na funkciyu drugogo tipa. Rezul'tat vyzova funkcii s
pomoshch'yu ukazatelya na funkciyu, tip kotoroj otlichen ot tipa,
ispol'zovannogo pri opredelenii pervoj funkcii, neopredelen
(sm. tak zhe $$R.4.6).
   Ob容kt ili znachenie mozhno preobrazovat' v ob容kt tipa klass
tol'ko pri uslovii, chto opredelen podhodyashchij konstruktor ili
operaciya preobrazovaniya ($$R.12.3).
  Ukazatel' na chlen mozhno yavno preobrazovat' v ukazatel' na drugoj
chlen, esli oba uchastvuyushchih tipa yavlyayutsya tipami ukazatelej
na chleny odnogo klassa, ili, esli oba tipa yavlyayutsya ukazatelyami
na funkciyu-chlen klassov, odin iz kotoryh poluchaetsya kak odnoznachnoe
proizvodnoe ot drugogo ($$R.4.8).
    Ukazatel' na ob容kt s tipom, imeyushchim specifikaciyu const, mozhno
privesti k ukazatelyu s tipom bez specifikacii const. Poluchivshijsya
v rezul'tate ukazatel' budet nastroen na ishodnyj ob容kt.
Ob容kt s tipom, imeyushchim specifikaciyu const, ili ssylku na ob容kt
takogo tipa mozhno privesti v ssylku na ob容kt s tipom bez const.
Poluchivshayasya v rezul'tate ssylka budet nastroena na ishodnyj
ob容kt. V rezul'tate popytki izmenit' etot ob容kt s pomoshch'yu
takoj ssylki ili ukazatelya mozhet vozniknut' osobaya situaciya ili
on budet takim zhe, kak pri obrashchenii s pomoshch'yu ishodnoj ssylki
ili ukazatelya k ob容ktu, tip kotorogo ne soderzhit const. Vozniknet
li osobaya adresnaya situaciya zavisit ot realizacii.
   Ukazatel' na ob容kt tipa so specifikaciej volatile mozhno privesti
k ukazatelyu na ob容kt tipa bez volatile. V rezul'tate poluchitsya
ukazatel', nastroennyj na ishodnyj ob容kt. Ob容kt tipa s volatile
ili ssylku na takoj ob容kt mozhno privesti k ssylke na ob容kt s tipom
bez volatile.



Operacii ukazatel'-na-chlen primenyayutsya sleva napravo.

     vyrazhenie-pm:
        vyrazhenie-privedeniya
        vyrazhenie-pm .*  vyrazhenie-privedeniya
        vyrazhenie-pm ->* vyrazhenie-privedeniya

    Binarnaya operaciya .* svyazyvaet svoj vtoroj operand, kotoryj dolzhen
imet' tip "ukazatel' na chlen klassa T", s pervym operandom, imeyushchim
tip klass T ili takoj klass, dlya kotorogo T yavlyaetsya odnoznachno
opredelennym i dostizhimym bazovym klassom. Rezul'tatom budet ob容kt
ili funkciya s tipom, zadavaemym vtorym operandom.
   Binarnaya operaciya ->* svyazyvaet svoj vtoroj operand, kotoryj dolzhen
imet' tip "ukazatel' na chlen klassa T", s pervym operandom, imeyushchim
tip "ukazatel' na T" ili tip "ukazatel' na klass, dlya kotorogo T
yavlyaetsya odnoznachno opredelennym i dostizhimym bazovym klassom".
Rezul'tatom budet ob容kt ili funkciya s tipom, zadavaemym vtorym
operandom.
 Esli rezul'tat .* ili ->* est' funkciya, to ego mozhno ispol'zovat'
tol'ko v kachestve operanda operacii vyzova funkcii (), naprimer,
operaciya

     (ptr_to_obj->*ptr_to_mfct)(10);

privodit k vyzovu funkcii-chlena, oboznachennoj ptr_to_mfct, dlya
ob容kta, na kotoryj nastroen ukazatel' ptr_to_obj. Rezul'tat
operacii .* ili ->* yavlyaetsya adresom, esli vtoroj operand est'
adres.



Mul'tiplikativnye operacii *, /, i % vypolnyayutsya sleva napravo.

    Mul'tiplikativnoe-vyrazhenie:
           vyrazhenie-pm
           mul'tiplikativnoe-vyrazhenie * vyrazhenie-pm
           mul'tiplikativnoe-vyrazhenie / vyrazhenie-pm
           mul'tiplikativnoe-vyrazhenie % vyrazhenie-pm

Operandy operacij * i / dolzhny imet' arifmeticheskij tip, operandy
dlya % dolzhny byt' celochislennogo tipa. Obychnye arifmeticheskie
preobrazovaniya ($$R.4.5) proizvodyatsya nad operandami i opredelyayut
tip rezul'tata.
    Binarnaya operaciya * oboznachaet umnozhenie.
    Binarnaya operaciya / vychislyaet chastnoe, a binarnaya operaciya %
vychislyaet ostatok ot deleniya pervogo vyrazheniya na vtoroe. Esli
vtoroj operand u / ili % est' 0, rezul'tat neopredelen, inache
(a/b)*b + a%b dolzhno ravnyat'sya a. Esli oba operanda neotricatel'ny,
to takim zhe budet i rezul'tat, v protivnom sluchae znak rezul'tata
opredelyaetsya realizaciej.


 R.5.7 Additivnye operacii

Additivnye operacii + i - vypolnyayutsya sleva napravo, pri etom
proishodyat obychnye arifmeticheskie preobrazovaniya ($$R.4.5)
operandov arifmeticheskogo tipa.

       additivnoe-vyrazhenie:
             mul'tiplikativnoe-vyrazhenie
             additivnoe vyrazhenie + mul'tiplikativnoe-vyrazhenie
             additivnoe-vyrazhenie - mul'tiplikativnoe-vyrazhenie

Operandy dolzhny byt' arifmeticheskogo tipa ili tipa ukazatelya.
Rezul'tatom operacii + yavlyaetsya summa operandov. Mozhno skladyvat'
ukazatel' na ob容kt v massive i znachenie lyubogo celochislennogo tipa.
Rezul'tatom budet ukazatel' togo zhe tipa, chto i ishodnyj ukazatel',
no on budet nastroen na drugoj ob容kt massiva
s zadannym smeshcheniem ot ishodnogo ob容kta. Tak, esli P
est' ukazatel' na ob容kt massiva, vyrazhenie P+1 yavlyaetsya ukazatelem
na sleduyushchij ob容kt massiva. Esli zhe poluchivshijsya v rezul'tate
slozheniya ukazatel' vyshel za granicy  massiva, rezul'tat budet
neopredelennym, krome sluchaya, kogda ukazatel' nastroen na pervyj adres
bol'shij verhnej granicy massiva.
    Rezul'tatom operacii - budet raznost' operandov. Znachenie
lyubogo celochislennogo tipa mozhno vychitat' iz ukazatelya, pri etom
primenyayutsya te zhe preobrazovaniya, chto i dlya operacii +.
    Nikakie drugie sochetaniya tipov dlya ukazatelej ne dopustimy.
    Esli vychitayutsya dva ukazatelya na ob容kty odnogo tipa, rezul'tatom
budet celochislennoe znachenie so znakom, kotoroe pokazyvaet na skol'ko
ob容ktov etogo tipa otstoyat drug ot druga ukazuemye ob容kty. Ukazateli
na sosednie elementy massiva otstoyat na 1. Tip rezul'tata zavisit ot
realizacii, no on dolzhen byt' opredelen kak ptrdiff_t v standartnom
zagolovochnom fajle <stddef.h>. Rezul'tat ne opredelen, esli ukazateli
ne nastroeny na elementy odnogo massiva. Esli P est' ukazatel'
na poslednij element massiva, to (P+1) - 1 est' P.



Operacii sdvigov << i >> vypolnyayutsya sleva napravo.

      sdvigovoe-vyrazhenie:
          additivnoe-vyrazhenie
          sdvigovoe-vyrazhenie << additivnoe vyrazhenie
          sdvigovoe-vyrazhenie >> additivnoe vyrazhenie

Operandy dolzhny byt' celochislennogo tipa, i nad nimi proizvodyatsya
standartnye celochislennye preobrazovaniya. Tip rezul'tata sovpadaet
s tipom preobrazovannogo levogo operanda. Rezul'tat ne opredelen,
esli pravyj operand otricatelen ili bol'she ili raven chislu razryadov
v dvoichnom predstavlenii preobrazovannogo levogo operanda.
Znacheniem vyrazheniya E1<<E2 budet E1 (rassmatrivaemoe kak nabor
razryadov), sdvinutoe vlevo na E2 razryadov, prichem osvobodivshiesya
razryady zapolnyayutsya nulyami. Znacheniem vyrazheniya E1>>E2 budet E1,
sdvinutoe vpravo na E2 razryadov. Esli E1 bezznakovogo tipa ili
imeet neotricatel'noe znachenie, garantiruetsya, chto sdvig vpravo
- logicheskij (zapolnenie nulyami), inache rezul'tat zavisit ot realizacii.



Operacii otnosheniya vypolnyayutsya sleva napravo, no etot fakt malo chto
daet, ibo vyrazhenie a<b<c oznachaet (a<b)<c, a vovse ne (a<b)&&(b<c).

       vyrazhenie-otnosheniya:
          sdvigovoe-vyrazhenie
          vyrazhenie-otnosheniya <  sdvigovoe-vyrazhenie
          vyrazhenie-otnosheniya >  sdvigovoe-vyrazhenie
          vyrazhenie-otnosheniya <= sdvigovoe-vyrazhenie
          vyrazhenie-otnosheniya >= sdvigovoe-vyrazhenie

Operandy dolzhny byt' arifmeticheskogo tipa ili tipa ukazatelej.
Operacii < (men'she chem), > (bol'she chem), <= (men'she ili ravno) i
>= (bol'she ili ravno) dayut rezul'tat 0, esli ukazannoe otnoshenie
ne vypolnyaetsya, i 1, esli ono vypolnyaetsya. Tip rezul'tata int.
   Nad arifmeticheskimi operandami vypolnyayutsya obychnye arifmeticheskie
preobrazovaniya. Nad ukazatelyami vypolnyayutsya obychnye preobrazovaniya
ukazatelej. Predpolagaetsya, chto lyuboj ukazatel' mozhno sravnit'
s vyrazheniem, imeyushchim rezul'tat 0, i lyuboj ukazatel' mozhno sravnit'
s ukazatelem, imeyushchim tip void* (v etom sluchae ukazatel' snachala
preobrazuetsya k tipu void*). Ukazateli na ob容kty ili funkcii
odnogo tipa (posle preobrazovaniya ukazatelej) mozhno sravnivat',
rezul'tat zavisit ot vzaimnogo raspolozheniya v pamyati ob容ktov ili
funkcij.
    Dva ukazatelya na odin i tot zhe ob容kt schitayutsya ravnymi. Esli
dva ukazatelya nastroeny na nestaticheskie chleny odnogo ob容kta, to
ukazatel', nastroennyj na chlen, opisannyj pozdnee, schitaetsya
bol'shim, pri uslovii, chto chleny ne imeyut raznyh specifikacij
ukazatel'-dostupa ($$R.11.1), a klass ne yavlyaetsya ob容dineniem.
Esli dva ukazatelya nastroeny na nestaticheskie chleny odnogo ob容kta
i specifikacii ukazatelej-dostupa ($$R.11.1) etih chlenov razlichny,
rezul'tat budet ne opredelen. Esli dva ukazatelya nastroeny na chleny
(dannye) odnogo i togo zhe ob容dineniya, oni schitayutsya ravnymi. Esli dva
ukazatelya nastroeny na elementy odnogo massiva ili smotryat za granicu
massiva, to ukazatel', nastroennyj na element s bol'shim indeksom,
budet bol'shim. Vse drugie sravneniya ukazatelej opredelyayutsya
realizaciej.



     vyrazhenie-ravenstva:
           vyrazhenie-otnosheniya
           vyrazhenie-ravenstva == vyrazhenie-otnosheniya
           vyrazhenie-ravenstva != vyrazhenie-otnosheniya

Operacii == (ravno) i != (ne ravno) analogichny operaciyam
otnosheniya, za isklyucheniem togo, chto ih prioritet nizhe. (Takim obrazom,
operaciya a<b == c<d daet rezul'tat 1, esli vyrazheniya a<b i c<d
imeyut odno i to zhe znachenie.)
    Krome etogo, mozhno sravnivat' ukazateli na chleny odnogo tipa.
Proizvodyatsya preobrazovaniya ukazatelya na chlen ($$R.4.8). Ukazatel'
na chlen mozhno sravnit' s vyrazheniem-konstantoj, kotoroe daet
rezul'tat 0.



     vyrazhenie-I:
          vyrazhenie-ravenstva
          vyrazhenie-I & vyrazhenie-ravenstva

Vypolnyayutsya obychnye arifmeticheskie preobrazovaniya, rezul'tat -
porazryadnaya funkciya I ot operandov.  Operaciya primenima tol'ko k
celochislennym operandam.



          vyrazhenie-isklyuchayushchego-ILI:
               vyrazhenie-I
               vyrazhenie-isklyuchayushchego-ILI ^ vyrazhenie-I

Vypolnyayutsya obychnye arifmeticheskie preobrazovaniya, rezul'tat -
porazryadnaya isklyuchayushchaya funkciya ILI ot operandov. Operaciya primenima
tol'ko k celochislennym operandam.



      vyrazhenie-ILI:
           vyrazhenie-isklyuchayushchego-ILI
           vyrazhenie-ILI | vyrazhenie-isklyuchayushchego-ILI

Vypolnyayutsya obychnye arifmeticheskie preobrazovaniya, rezul'tat -
porazryadnaya funkciya ILI ot operandov. Operaciya primenima tol'ko
k celochislennym tipam.



        logicheskoe-vyrazhenie-I:
             vyrazhenie-ILI
             logicheskoe-vyrazhenie-I && vyrazhenie-ILI

Operacii && vypolnyayutsya sleva napravo. Takaya operaciya daet rezul'tat
1, esli oba operanda ee otlichny ot nulya, inache rezul'tat - 0. V
otlichie ot & pri operacii && garantiruetsya vychislenie sleva napravo,
bolee togo, vtoroj operand ne vychislyaetsya, esli pervyj operand raven 0.
    Operandy ne obyazatel'no imeyut odinakovyj tip, no kazhdyj dolzhen byt'
arifmeticheskogo tipa ili tipa ukazatelya. Tip rezul'tata int. Vse
pobochnye effekty vychisleniya pervogo vyrazheniya mogut voznikat' do
vychisleniya vtorogo vyrazheniya.



        logicheskoe-vyrazhenie-ILI:
             logicheskoe-vyrazhenie-I
             logicheskoe-vyrazhenie-ILI || logicheskoe-vyrazhenie-I

Operacii || vypolnyayutsya sleva napravo. Rezul'tat operacii 1, esli
odin iz ee operandov otlichen ot nulya, inache rezul'tat - 0. V otlichie
ot | pri operacii || garantiruetsya vychislenie sleva napravo, bolee
togo, vtoroj operand ne vychislyaetsya, esli znachenie pervogo operanda
otlichno ot nulya.
   Operandy ne obyazatel'no imeyut odinakovyj tip, no kazhdyj dolzhen byt'
arifmeticheskogo tipa ili tipa ukazatelya. Tip rezul'tata int. Vse
pobochnye effekty vychisleniya pervogo vyrazheniya mogut voznikat' do
vychisleniya vtorogo vyrazheniya.



        vyrazhenie-usloviya:
             logicheskoe-vyrazhenie-ILI
             logicheskoe-vyrazhenie-ILI ? vyrazhenie : vyrazhenie-usloviya

Uslovnye vyrazheniya vypolnyayutsya sleva napravo. Pervoe vyrazhenie dolzhno
byt' arifmeticheskogo tipa ili tipa ukazatelya. Ono vychislyaetsya, i,
esli rezul'tat ego otlichen ot nulya, to rezul'tatom uslovnogo vyrazheniya
budet znachenie vtorogo vyrazheniya, inache rezul'tat - znachenie tret'ego
vyrazheniya. Vse pobochnye effekty vychisleniya pervogo vyrazheniya mogut
voznikat' do vychisleniya vtorogo ili tret'ego vyrazheniya.
      Esli vtoroe i tret'e vyrazhenie arifmeticheskogo tipa, i tipy ih
sovpadayut, to takim zhe budet i tip rezul'tata, esli oni razlichayutsya, to
vypolnyayutsya obychnye arifmeticheskie preobrazovaniya, chtoby privesti ih
k obshchemu tipu. Esli vtoroe i tret'e vyrazhenie yavlyayutsya
ukazatelyami ili vyrazheniem-konstantoj, dayushchim rezul'tat 0, vypolnyayutsya
preobrazovaniya ukazatelej, chtoby privesti rezul'taty vyrazhenij k
obshchemu tipu. Esli vtoroe i tret'e vyrazhenie yavlyayutsya ssylkami,
vypolnyaetsya preobrazovanie ssylok, chtoby privesti ih k obshchemu tipu.
Esli vtoroe i tret'e vyrazhenie imeyut tip void, obshchij tip
budet void. Esli vtoroe i tret'e vyrazhenie imeyut odin tip
klass T, obshchim tipom budet T. Inache, vyrazhenie schitaetsya nedopustimym.
Tip rezul'tata est' obshchij tip. Vychislyaetsya tol'ko vtoroe ili tret'e
vyrazhenie (no ne oba). Rezul'tat budet adresom, esli vtoroj i
tretij operand odnogo tipa i yavlyayutsya adresami.



Sushchestvuet neskol'ko operacij prisvaivaniya, vse oni vypolnyayutsya
sprava nalevo. Dlya vseh nih trebuetsya, chtoby levym operandom byl
izmenyaemyj adres. Tip vyrazheniya prisvaivaniya sovpadaet s tipom
levogo operanda. Rezul'tat operacii prisvaivanie - znachenie,
hranyashcheesya v levom operande posle togo kak proizoshlo prisvaivanie.
Rezul'tat yavlyaetsya adresom.

      vyrazhenie-prisvaivaniya:
         vyrazhenie-usloviya
         unarnoe-vyrazhenie operaciya-prisvaivaniya vyrazhenie-prisvaivaniya
         operaciya-prisvaivaniya: odin iz
              =  *=  /=  %=  +=  -=  >>=  <<=  &=  ^=  |=

Pri prostom prisvaivanii (=) znachenie vyrazheniya zamenyaet soboj znachenie
ob容kta, s kotorym sopostavlyaetsya levyj operand. Esli oba operanda
arifmeticheskogo tipa, pravyj operand, prezhde chem proizojdet
prisvaivanie, preobrazuetsya k tipu levogo operanda. Neyavnye
preobrazovaniya k tipu perechisleniya ($$R.7.2) ne proizvodyatsya, poetomu
esli levyj operand imeet tip perechisleniya, pravyj operand dolzhen
byt' takim zhe. Esli levyj operand imeet tip ukazatelya, pravyj
operand dolzhen byt' tipa ukazatelya ili vyrazheniem-konstantoj, dayushchim
rezul'tat 0. Pravyj operand preobrazuetsya k tipu levogo operanda,
prezhde vypolneniya prisvaivaniya.
   Ukazatel' tipa T* const mozhno prisvaivat' ukazatelyu tipa T*, no
obratnoe prisvaivanie schitaetsya nezakonnym ($$R.7.1.6). Ob容kty
tipa const T ili volatile T mozhno prisvaivat' po adresu tipa T ili
volatile T (sm. tak zhe $$R.8.4).
   Esli levyj operand imeet tip ukazatelya na chlen, pravyj operand
dolzhen byt' tipa ukazatel' na chlen ili vyrazheniem-konstantoj,
dayushchim rezul'tat 0; pered prisvaivaniem pravyj operand preobrazuetsya
k tipu levogo operanda.
   Prisvaivanie ob容ktam klassa X ($$R.9) zadaetsya funkciej
X::operator=() ($$R.13.4.3). Esli pol'zovatel' ne opredelil
svoyu funkciyu X::operator=(), dlya prisvaivaniya ispol'zuetsya
standartnyj variant ($$R.12.8).  Otsyuda sleduet, chto ob容kt klassa,
kotoryj yavlyaetsya pryamym ili nepryamym proizvodnym ot X,  i
odnoznachno opisan kak proizvodnyj v chasti public ($$R.4.6),
mozhno prisvoit' ob容ktu X.
    Ukazatel' na chlen klassa B mozhno prisvaivat' ukazatelyu na chlen
togo zhe tipa klassa D pri uslovii, chto D yavlyaetsya pryamym ili
nepryamym proizvodnym klassa B, i odnoznachno opisan kak
proizvodnyj v chasti public ($$R.10.1.1).
    Prisvaivanie ob容ktu tipa "ssylka na T" svoditsya k prisvaivaniyu
ob容ktu tipa T, kotoryj oboznachaetsya ssylkoj.
   Vypolnenie vyrazhenie vida E1 op= E2 ekvivalentno vypolneniyu
E1 = E1 op (E2), odnako E1 vychislyaetsya lish' odin raz. V operaciyah
+= i -= levyj operand mozhet byt' ukazatelem, v etom sluchae pravyj
(celochislennyj) operand preobrazuetsya tak, kak ob座asnyalos' v $$R.5.7.
Vse pravye operandy i vse levye operandy, ne yavlyayushchiesya ssylkami,
dolzhny byt' arifmeticheskogo tipa.
   Dlya ob容ktov klassa prisvaivanie v obshchem sluchae ne sovpadaet s
inicializaciej ($$R.8.4, $$R.12.1, $$R.12.6, $$R.12.8).



Operacii zapyataya vypolnyayutsya sleva napravo.

       vyrazhenie:
            vyrazhenie-prisvaivaniya
            vyrazhenie, vyrazhenie-prisvaivaniya

Para vyrazhenij, razdelennyh zapyatoj, vychislyaetsya sleva napravo i
znachenie levogo vyrazheniya unichtozhaetsya. Vse pobochnye effekty vychisleniya
levogo vyrazheniya mogut voznikat' do vychisleniya pravogo vyrazheniya.
Tip i znachenie rezul'tata sovpadayut s tipom i znacheniem pravogo
vyrazheniya. Rezul'tat yavlyaetsya adresom, esli takovym yavlyaetsya
pravoe vyrazhenie.
    V kontekstah, gde zapyataya imeet special'noe znachenie, skazhem
v spiske fakticheskih parametrov funkcii ($$R.5.2.2) ili v spiske
inicializatorov ($$R.8.4), opisannaya zdes' operaciya zapyataya
mozhet poyavlyat'sya tol'ko v skobkah, naprimer, vyzov funkcii

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

soderzhit tri parametra, prichem vtoroj imeet znachenie 5.



V neskol'kih mestah opisaniya S++ trebuyutsya vyrazheniya, kotorye
dayut v rezul'tate celochislennuyu konstantu, naprimer: v zadanii granic
massiva ($$R.8.2.4), v vyrazheniyah case ($$R.6.4.2),
dlya zadaniya dliny bitovogo polya ($$R.9.6) i kak inicializiruyushchee
znachenie elementa perechisleniya ($$R.7.2).

       vyrazhenie-konstanta:
             vyrazhenie-usloviya

V konstrukcii vyrazhenie-konstanta mogut uchastvovat': literaly
($$R.2.5), elementy perechisleniya, znacheniya celochislennogo tipa so
specifikaciej const, inicializirovannye vyrazheniem-konstantoj
($$R.8.4) i vyrazheniya sizeof. Konstanty s plavayushchej tochkoj ($$R.2.5.3)
dolzhny byt' privedeny k celochislennomu tipu. Dopustimy tol'ko
preobrazovaniya tipa k celochislennomu tipu. V chastnosti ne dopustimy
funkcii, ob容kty klassov, ukazateli i ssylki, esli ne schitat' ih
ispol'zovaniya v sizeof. Operaciya zapyataya i operaciya prisvaivaniya
ne dopustimy v vyrazhenii-konstante.



Vse operatory, za isklyucheniem ogovorennyh sluchaev, vypolnyayutsya
odin za drugim.

     operator:
       pomechennyj-operator
       operator-vyrazhenie
       sostavnoj-operator
       vybirayushchij-operator
       operator-cikla
       operator-perehoda
       operator-opisaniya



Operator mozhno snabdit' metkoj.

       pomechennyj-operator:
           identifikator : operator
           case vyrazhenie-konstanta : operator
           default : operator

Ispol'zovanie identifikatora v kachestve metki yavlyaetsya ee opredeleniem.
Identifikator metki mozhet ispol'zovat'sya pomimo etogo tol'ko v kachestve
ukazaniya perehoda v operatore goto. Oblast'yu vidimosti metki yavlyaetsya
funkciya, v kotoroj ona poyavilas'. Metki nel'zya povtorno opisyvat'
v predelah odnoj funkcii. Nel'zya ispol'zovat' metku v operatore goto
do ee opredeleniya. Metki imeyut svoe prostranstvo imenovaniya i
oni ne vstupayut v kolliziyu s drugimi identifikatorami.
    Metki v case ili default mogut vstrechat'sya tol'ko v operatore
pereklyuchatelya.



CHashche vsego operatorami byvayut vyrazheniya; v etom sluchae operator
imeet takoj vid:

        operator-vyrazhenie:
            vyrazhenie opt ;

Obychno operatory-vyrazheniya yavlyayutsya prisvaivaniyami ili vyzovami
funkcij. Vse pobochnye effekty vypolneniya operatora-vyrazheniya
proishodyat do vypolneniya sleduyushchego operatora. Operator-vyrazhenie s
otsutstvuyushchim vyrazheniem nazyvaetsya pustym operatorom. On
mozhet prigodit'sya, esli neobhodimo postavit' metku pered samym koncom
sostavnogo operatora ({) ili dlya zadaniya pustogo tela operatora
cikla while ($$R.6.5.1).



Dlya teh sluchaev, kogda vmesto odnogo operatora nuzhno ispol'zovat'
neskol'ko, predusmotren sostavnoj operator (inogda ego nazyvayut
"blok").

           sostavnoj-operator:
               { spisok-operatorov opt }

           spisok-operatorov:
                operator
                spisok-operatorov operator

Otmetim, chto opisanie schitaetsya operatorom ($$R.6.7).



Vybirayushchie operatory vybirayut odnu iz neskol'kih struktur upravleniya.

        vybirayushchij-operator:
             if ( vyrazhenie ) operator
             if ( vyrazhenie ) operator else operator
             switch ( vyrazhenie ) operator

Operator v vybirayushchem-operatore ne mozhet byt' opisaniem.



Vyrazhenie dolzhno byt' arifmeticheskogo tipa, ili tipa ukazatelya, ili
tipa klass, dlya kotorogo sushchestvuet odnoznachnoe preobrazovanie
v arifmeticheskij tip ili tip ukazatelya ($$R.12.3).
    Vychislyaetsya vyrazhenie, i esli ono imeet otlichnyj ot nulya rezul'tat,
vypolnyaetsya pervyj vlozhennyj operator. Esli ispol'zovana konstrukciya
else i vyrazhenie daet rezul'tat 0, vypolnyaetsya vtoroj vlozhennyj
operator. Neodnoznachnost' v sluchae neskol'kih konstrukciyami else
razreshaetsya putem otneseniya else k poslednemu vstretivshemusya if,
dlya kotorogo ne bylo else.



Operator pereklyuchatelya vyzyvaet peredachu upravleniya na odin iz
neskol'kih operatorov v zavisimosti ot znacheniya vyrazheniya.
    Vyrazhenie dolzhno byt' celochislennogo tipa ili tipa klassa, dlya
kotorogo sushchestvuet odnoznachnoe preobrazovanie k celochislennomu
tipu ($$R.12.3). Vypolnyayutsya standartnye celochislennye preobrazovaniya.
Lyuboj iz operatorov pereklyuchatelya mozhno pometit' odnim ili neskol'kimi
prefiksami, imeyushchimi vid:

     case vyrazhenie-konstanta :

Zdes' vyrazhenie-konstanta ($$R.5.19) privoditsya k preobrazovannomu
tipu vyrazheniya pereklyuchatelya. Nikakie dve konstanty iz case odnogo
pereklyuchatelya ne dolzhny imet' odinakovoe znachenie.
    V pereklyuchatele mozhet byt' tol'ko odin prefiks vida

     default:

   Operatory pereklyuchatelya mogut byt' vlozhennymi, togda metki iz
case ili default otnosyatsya k samomu pervomu pereklyuchatelyu,
ob容mlyushchemu ih.
   Pri vypolnenii operatora pereklyuchatelya vychislyaetsya vyrazhenie,
 i ego znachenie sravnivaetsya s kazhdoj iz konstant variantov (case).
Esli odna iz etih konstant ravna znacheniyu vyrazheniya, to upravlenie
peredaetsya v operator, idushchij za etoj konstantoj. Esli ni odna iz
konstant ne sovpala so znacheniem vyrazheniya, no est' prefiks
default, to upravlenie peredaetsya na operator s etim prefiksom.
Esli prefiksa default net, i sovpadeniya ne bylo, to ne vypolnyaetsya
ni odin iz operatorov pereklyuchatelya.
   Esli operatory, vypolnyaemye v rezul'tate vybora, ne privodyat
k kakim-libo peredacham upravleniya, to programma prodolzhaet vypolnyat'sya
"po metkam case i default" besprepyatstvenno. Vyhod iz pereklyuchatelya
vozmozhen s pomoshch'yu operatora break (sm. $$R.6.6.1).
   Obychno operator, s kotorym imeet delo pereklyuchatel', byvaet
sostavnym. Opisaniya mogut poyavit'sya v operatorah pereklyuchatelya.
Odnako perehod nizhe opisaniya, v kotorom byla yavnaya ili neyavnaya
inicializaciya, schitaetsya nezakonnym, esli tol'ko opisanie ne
nahoditsya vo vnutrennem bloke, kotoryj obhoditsya (t.e. polnost'yu
obhoditsya pri peredache upravleniya, $$R.6.7). Otsyuda sleduet,
chto opisanie s yavnoj ili neyavnoj inicializaciej dolzhno soderzhat'sya
vo vnutrennem bloke.



|ti operatory zadayut vidy cikla.

    operator-cikla:
          while ( vyrazhenie ) operator
          do operator  while (vyrazhenie)
          for ( operator-inic vyrazhenie opt ; vyrazhenie opt ) operator
          operator-inic:
                  operator-vyrazhenie
                  operator-opisanie

  Obratite vnimanie, chto konstrukciya operator-inic konchaetsya tochkoj s
zapyatoj.
  Operator v operatore-cikla ne dolzhen byt' opisaniem.



V operatore while vlozhennyj operator vypolnyaetsya do teh por,
poka znachenie vyrazheniya ne stanet ravnym nulyu. Proverka proishodit
pered kazhdym vypolneniem operatora.
  Vyrazhenie dolzhno byt' arifmeticheskogo tipa, ili tipa ukazatelya, ili
tipa klass, dlya kotorogo sushchestvuet odnoznachnoe preobrazovanie v
arifmeticheskij tip ili tip ukazatelya ($$R.12.3).



V operatore do vlozhennyj operator vypolnyaetsya do teh por,
poka znachenie vyrazheniya ne stanet ravnym nulyu. Proverka proishodit
posle kazhdogo vypolneniya operatora.
    Vyrazhenie dolzhno byt' arifmeticheskogo tipa, ili tipa ukazatelya,
ili tipa klass, dlya kotorogo sushchestvuet odnoznachnoe preobrazovanie
v arifmeticheskij tip ili tip ukazatelya ($$R.12.3).



Operator for
   for (operator-inic vyrazhenie-1 opt ; vyrazhenie-2 opt ) operator
ekvivalenten konstrukcii
   operator-inic
   while (vyrazhenie-1) {
         operator
         vyrazhenie-2 ;
   }

za isklyucheniem togo fakta, chto operator continue v operatore for
vyzovet vypolnenie vyrazhenie-2 pered tem& kak nachat' povtornoe
vychislenie vyrazheniya-1. Takim obrazom, pervyj operator zadaet
inicializaciyu dlya cikla, pervoe vyrazhenie proizvodit proverku,
vypolnyaemuyu pered kazhdym shagom cikla, tak chto cikl zavershaetsya, kogda
vyrazhenie stanovitsya nulem, a vtoroe vyrazhenie obychno zadaet
prirashchenie, i ono dobavlyaetsya posle kazhdogo shaga cikla. Pervoe
vyrazhenie dolzhno imet' arifmeticheskij tip, ili tip ukazatelya, ili
tip klassa, dlya kotorogo sushchestvuet odnoznachnoe preobrazovanie
k arifmeticheskomu tipu ili tipu ukazatelya ($$R.12.3).
    Mogut byt' opushcheny odno ili oba vyrazheniya. Esli otsutstvuet
vyrazhenie-1, to ekvivalentnyj cikl s while imeet uslovie while (1).
    Esli operator-inic yavlyaetsya opisaniem, oblast' vidimosti imen,
opisannyh v nem, prostiraetsya do konca bloka, zakryvayushchego operator
for.



Operatory perehoda delayut bezuslovnuyu peredachu upravleniya.

     operator-perehoda:
           break ;
           continue ;
           return vyrazhenie opt ;
           goto identifikator ;

  Po vyhode iz oblasti vidimosti (kakim by obrazom eto ne proizoshlo)
vyzyvayutsya destruktory ($$R.12.4) dlya vseh ob容ktov klassov,
postroennyh v etoj oblasti, kotorye eshche ne byli unichtozheny. |to
otnositsya kak k yavno opisannym ob容ktam, tak i ko vremennym ob容ktam
($$R.12.2).



Operator break mozhet vstretit'sya tol'ko v operatore cikla ili
pereklyuchatele, on privodit k okonchaniyu blizhajshego iz ob容mlyushchih
ego operatorov cikla ili pereklyuchatelej. Upravlenie peredaetsya na
operator, sleduyushchij neposredstvenno za zakanchivaemym, esli takoj est'.



Operator continue mozhet vstretit'sya tol'ko v operatore cikla i
privodit k peredache upravleniya v zagolovok blizhajshego
iz ob容mlyushchih operatorov cikla, t.e. v konec cikla. Bolee tochno
mozhno skazat', chto v kazhdom iz operatorov:

    while (foo) {      do  {           for (;;) {
    // ...             // ...          // ...
    contin: ;          contin: ;       contin: ;
    }                  } while (foo);  }

operator continue, ne otnosyashchijsya ko vneshnim operatoram cikla,
ekvivalenten operatoru goto contin.



Vozvrat iz funkcii v obrativshuyusya k nej funkciyu proishodit s pomoshch'yu
operatora return.
   Operator return bez vyrazheniya mozhno ispol'zovat' tol'ko v
funkciyah, kotorye ne vozvrashchayut znachenie, t.e. v funkciyah,
vozvrashchayushchih znachenie tipa void, ili v konstruktorah ($$R.12.1)
i destruktorah ($$R.12.4). Operator return s vyrazheniem mozhno
ispol'zovat' tol'ko v funkciyah, kotorye vozvrashchayut znachenie. Znachenie
vyrazheniya peredaetsya v tu funkciyu,kotoraya vyzvala dannuyu funkciyu. Esli
nuzhno, znachenie preobrazuetsya k tipu funkcii, v kotoroj vypolnyaetsya
return, po tem zhe pravilam kak pri inicializacii. |to mozhet privesti
k vyzovu konstruktora ili kopirovaniyu vremennyh ob容ktov ($$R.12.2).
Vyhod iz funkcii po koncu ekvivalenten vozvratu bez vydavaemogo
znacheniya, chto yavlyaetsya nezakonnym dlya funkcii, vozvrashchayushchej
znachenie.



Operator goto bezuslovno peredaet upravlenie na operator,
pomechennyj identifikatorom. Identifikator dolzhen byt' metkoj
($$R.6.1), nahodyashchejsya v tekushchej funkcii.



Operator opisaniya zavodit v bloke novyj identifikator i imeet
vid:

     operator-opisaniya:
    opisanie

Esli identifikator, vvedennyj s pomoshch'yu opisaniya, uzhe byl ranee
opisan vo vneshnem bloke, vneshnee opisanie stanovitsya skrytym do
konca bloka, posle chego ono opyat' vstupaet v silu.
    Vse inicializacii avtomaticheskih (auto) i registrovyh (register)
peremennyh proizvodyatsya kazhdyj raz, kogda vypolnyaetsya
operator-opisanie. Unichtozhenie lokal'nyh peremennyh, opisannyh v
bloke, proishodit pri vyhode iz bloka ($$R.6.6). Unichtozhenie
avtomaticheskih peremennyh, opredelennyh v cikle, proishodit
na kazhdom shage cikla. Naprimer, peremennaya Index j sozdaetsya i
unichtozhaetsya kazhdyj raz v techenie cikla po i:

     for (int i = 0; i<100; i++)
  for (Index j = 0; j<100; j++) {
  // ...
  }

Vyhod iz cikla ili iz bloka ili perehod, minuya inicializaciyu
avtomaticheskih peremennyh, privodit k unichtozheniyu avtomaticheskih
peremennyh, opisannyh v tochke, otkuda proishodit perehod, no ne
v tochke, kuda proishodit perehod.
    Perehod v blok vozmozhen pri uslovii, chto on ne privodit k
propusku inicializacii. Schitaetsya nezakonnym perehod, obhodyashchij
opisanie s yavnoj ili neyavnoj inicializaciej, krome sluchaev, kogda
ono nahoditsya vo vnutrennem bloke, kotoryj propuskaetsya (t.e. v nego
nikogda ne popadaet upravlenie) ili perehod proishodit iz toj tochki,
gde uzhe byla inicializaciya peremennoj. Naprimer,

     void f()
     {
 // ...
 goto lx;  //oshibka: perehod, minuya inicializaciyu
 // ...
     ly:
  X a = 1;
  // ...
     lx:
  goto ly; // normal'no, za perehodom budet vyzov
           // destruktora dlya `a'
     }

 Avtomaticheskaya peremennaya, kotoraya byla sozdana pri nekotorom
 uslovii, unichtozhaetsya pri vypolnenii etogo usloviya, i ne mozhet
 byt' dostupna vne proverki etogo usloviya. Naprimer,

 if (i)
         for (int j = 0; j<100; j++) {
         // ...
 }
 if (j!=100)  // oshibka: obrashchenie vne usloviya
  // ...
  ;

  Inicializaciya lokal'nogo ob容kta s klassom pamyati static ($$R.7.1.1)
proizvoditsya prezhde, chem upravlenie  projdet cherez oblast' ego
opisaniya. Esli staticheskaya peremennaya inicializiruetsya vyrazheniem,
kotoroe ne yavlyaetsya vyrazheniem-konstantoj, to pered pervym vhodom
v blok proishodit standartnaya inicializaciya nulem, privedennym
k nuzhnomu tipu ($$R.8.4).
    Destruktor dlya lokal'nogo staticheskogo ob容kta budet vyzyvat'sya
v tom i tol'ko v tom sluchae, esli peremennaya byla sozdana s pomoshch'yu
konstruktora. Destruktor dolzhen vyzyvat'sya srazu pered vyzovom ili
kak sostavnaya chast' vyzova funkcij, zadannyh v atexit() ($$R.3.4).



Sushchestvuet neodnoznachnost' v grammatike yazyka, kasayushchayasya
operatora-vyrazheniya i opisaniya, a imenno, operator-vyrazhenie,
soderzhashchij kak samoe levoe podvyrazhenie yavnoe preobrazovanie tipa,
zadannoe v funkcional'nom stile ($$R.5.2.3), mozhet byt' ne otlichim ot
opisaniya, v kotorom pervyj opisatel' nachinaetsya so (. V takih sluchayah
operator schitaetsya opisaniem.
    Dlya razresheniya neodnoznachnosti sleduet issledovat' ves' operator,
chtoby opredelit' yavlyaetsya on operatorom-vyrazheniem ili opisaniem.
Tak ustranyaetsya neodnoznachnost' vo mnogih sluchayah. Naprimer, pust'
T - imya-prostogo-tipa ($$R.7.1.6), togda imeem

    T(a)->m = 7;       // operator-vyrazhenie
    T(a)++;            // operator-vyrazhenie
    T(a,5)<<c;         // operator-vyrazhenie

    T(*e)(int);        // opisanie
    T(f)[];            // opisanie
    T(g) = {1, 2 };    // opisanie
    T(*d)(double(3));  // opisanie

  Ostal'nye sluchai predstavlyayut opisaniya. Naprimer,

    T(a);         // opisanie
    T(*b)();      // opisanie
    T(c)=7;       // opisanie
    T(d),e,f=3;   // opisanie
    T(g)(h,2);    // opisanie

   Neodnoznachnost' zdes' chisto sintaksicheskaya, t.e. na ee
razreshenie ne vliyaet tot fakt, yavlyaetsya li imya imenem-tipa ili net.
   Est' drugoj vid kollizii mezhdu operatorom-vyrazheniem i opisaniem,
kotoryj razreshaetsya trebovaniem, chtoby opisanie funkcii v bloke
($$R.6.3) soprovozhdalos' imenem-tipa, naprimer:

    void g()
    {
      int f();  // opisanie
      int a;    // opisanie
      f();      // operator-vyrazhenie
      a;        // operator-vyrazhenie
   }



Opisaniya ispol'zuyutsya dlya interpretacii kazhdogo iz identifikatorov;
neobyazatel'no, chtoby oni soprovozhdalis' vydeleniem pamyati,
sopostavlyaemoj s identifikatorom. Opisaniya imeyut vid

       opisaniya:
              specifikacii-opisaniya opt spisok-opisatelej opt ;
              opisanie-asm
              opredelenie-funkcii
              specifikaciya-svyazi

Opisateli v spiske-opisatelej ($$R.8) soderzhat opisyvaemye
identifikatory. Konstrukciya specifikacii-opisaniya mozhet otsutstvovat'
tol'ko v opredelenii funkcij ($$R.8.3) ili v opisanii funkcij.
Spisok-opisatelej mozhet byt' pustym, tol'ko pri opisanii klassa ($$R.9)
ili perechisleniya ($$R.7.2), t.e. kogda specifikaciya-opisaniya est'
specifikaciya-klassa ili specifikaciya-perechisleniya.
Konstrukciya opisanie-asm ob座asnyaetsya v $$R.7.3, a specifikaciya-svyazi
v $$R.7.4. Opisanie proishodit v opredelennoj oblasti vidimosti
($$R.3.2), pravila oblasti vidimosti privodyatsya v $$R.10.4.



V opisanii mozhno ispol'zovat' sleduyushchie specifikacii:

        specifikaciya-opisaniya:
             specifikaciya-klassa-pamyati
             specifikaciya-tipa
             specifikaciya-fct
             specifikaciya-shablona-tipa
             friend
             typedef
        specifikacii-opisaniya:
             specifikacii-opisaniya opt specifikaciya-opisaniya

    Samaya dlinnaya posledovatel'nost' konstrukcij specifikaciya-opisaniya,
kotoraya, vozmozhno, yavlyaetsya imenem tipa, obrazuet v opisanii konstrukciyu
specifikacii-opisaniya. Posledovatel'nost' dolzhna byt' soglasovannoj,
chto ob座asnyaetsya nizhe. Naprimer,

      typedef char* Pc;
      static Pc;        // oshibka: net imeni

Zdes' opisanie static Pc yavlyaetsya nezakonnym, poskol'ku ne ukazano
nikakogo imeni staticheskoj peremennoj tipa Pc. CHtoby imet'
peremennuyu tipa int s imenem Pc, neobhodimo zadat'
specifikaciyu-tipa int, chtoby pokazat', chto (pere)opredelyaetsya
imya Pc iz typedef, a ne prosto Pc yavlyaetsya odnim iz elementov
posledovatel'nosti konstrukcij specifikaciya-opisaniya, naprimer,

      void f(const Pc);      // void f(char* const)
      void g(const int Pc);  // void g(const int)

    Ukazhem, chto poskol'ku signed, unsigned, long i short po
umolchaniyu traktuyutsya kak int, konstrukciya imya-typedef, kotoraya
poyavlyaetsya posle odnoj iz perechislennyh specifikacij tipa,
dolzhna zadavat' (pere)opredelyaemoe imya, naprimer,

      void h(unsigned Pc);     // void h(unsigned int)
      void k(unsigned int Pc); // void k(unsigned int)



Specifikacii klassa pamyati mogut byt' takie:

      specifikaciya-klassa-pamyati:
           auto
           register
           static
           extern

   Specifikacii auto i register mogut primenyat'sya tol'ko dlya
imen ob容ktov, kotorye opisany v bloke ($$R.6.3), ili dlya formal'nyh
parametrov ($$R.8.3). Pochti vsegda specifikaciya auto izbytochna i
ispol'zuetsya ne chasto, tak, auto ispol'zuetsya, chtoby yavno otdelit'
operator-opisanie ot operatora-vyrazheniya ($$R.6.2).
   Opisanie register yavlyaetsya opisaniem auto, kotoroe podskazyvaet
translyatoru, chto opisyvaemye peremennye budut ispol'zovat'sya
dostatochno intensivno. Podskazka mozhet byt' proignorirovana, i vo
mnogih realizaciyah ona ignoriruetsya v tom sluchae, kogda beretsya
adres peremennoj.
   Opisanie ob容kta schitaetsya opredeleniem, esli tol'ko ono ne
soderzhit specifikacii extern i inicializacii ($$R.3.1).
   Opredelenie privodit k vydeleniyu pamyati sootvetstvuyushchego
razmera i vypolneniyu sootvetstvuyushchej inicializacii ($$R.8.4).
   Specifikacii static i extern mogut primenyat'sya tol'ko k imenam
ob容ktov ili funkcij ili k anonimnym ob容dineniyam. Vnutri bloka
nedopustimy opisaniya funkcij so specifikaciej static ili
formal'nyh parametrov so specifikaciej static ili extern.
Staticheskie chleny klassa opisyvayutsya v $$R.9.4. Specifikaciya
extern nedopustima dlya chlenov klassa.
   Imya so specifikaciej static podlezhit vnutrennemu svyazyvaniyu.
Ob容kty, opisannye kak const, podlezhat vnutrennemu svyazyvaniyu,
esli tol'ko oni ne byli opisany s vneshnej svyaz'yu. Imya so
specifikaciej extern podlezhit vneshnemu svyazyvaniyu, esli tol'ko ranee
ono ne bylo opisano s vnutrennej svyaz'yu. Imya s fajlovoj oblast'yu
vidimosti i bez specifikacii-klassa-pamyati podlezhit vneshnemu
svyazyvaniyu, esli tol'ko ranee ono ne bylo opisano s vnutrennej
svyaz'yu ili so specifikaciej const. V smysle svyazyvaniya dlya funkcij,
ne yavlyayushchihsya chlenami, specifikaciya inline ekvivalentna static
($$R.3.3). Dlya odnogo imeni vse ego specifikacii, opredelyayushchie
svyazyvanie, dolzhny byt' soglasovany. Naprimer,

   static char* f();     // f() imeet vnutrennee svyazyvanie
   char* f()             // f() vse eshche vnutrennee
      { /* ... */ }

   char* g();            // g() imeet vneshnee svyazyvanie
   static char* g()      // oshibka: protivorechie v svyazyvanii
      { /* ... */ }

    static int a;        // `a' imeet vnutrennee svyazyvanie
    int a;               // oshibka: vtoroe opredelenie

    static int b;        // `b' imeet vnutrennee svyazyvanie
    extern int b;        // `b' vse eshche vnutrennee

    int c;               // `c' imeet vneshnee svyazyvanie
    static int c;        // oshibka: protivorechie v svyazyvanii

    extern int d;        // `d' imeet vneshnee svyazyvanie
    static int d;        // oshibka: protivorechie v svyazyvanii

    Imya neopredelennogo klassa mozhno ispol'zovat' v opisanii
extern. Odnako, takoe opisanie nel'zya ispol'zovat' prezhde, chem
klass budet opredelen, naprimer,

    struct S;
    extern S a;
    extern S f();
    extern void g(S);

    void h()
    {
      g(a);    // oshibka: S neopredeleno
      f();     // oshibka: S neopredeleno
    }



Nekotorye specifikacii mozhno ispol'zovat' tol'ko v opisanii funkcij.

    specifikaciya-fct:
         inline
         virtual

  Specifikaciya inline podskazyvaet translyatoru, chto neobhodimo
proizvesti podstanovku tela funkcii vmesto obychnoj realizacii
vyzova funkcii. Podskazka mozhet ignorirovat'sya. V sluchae funkcij,
ne yavlyayushchihsya chlenami, specifikaciya inline dopolnitel'no ustanavlivaet
dlya funkcii vnutrennee svyazyvanie ($$R.3.3). Funkciya ($$R.5.2.2,
$$R.8.2.5), opredelennaya v opisanii klassa, imeet po umolchaniyu
specifikaciyu inline.
   Funkciya-chlen so specifikaciej inline dolzhna imet' v tochnosti
takoe zhe opredelenie v kazhdoj edinice translyacii, gde ona poyavlyaetsya.
   Funkciyu-chlen ne obyazatel'no yavno opisyvat' so specifikaciej
inline pri opisanii klassa, chtoby ona traktovalas' kak podstanovka.
Esli specifikacii inline ne bylo, svyazyvanie budet vneshnim,
esli tol'ko opredelenie so specifikaciej inline ne poyavitsya pered
pervym vyzovom funkcii.

     class X {
     public:
       int f();
       inline int g();    // X::g() imeet vnutrennee svyazyvanie
       int h();
     };

     void k(X* p)
     {
       int i = p->f();    // teper' X::f() vneshnee svyazyvanie
       int j = p->g();
       // ...
     }

    inline int X::f()    // oshibka: vyzov do opredeleniya
                         // kak inline
    {
      // ...
    }

   inline int X::g()
   {
     // ...
   }

   inline int X::h()     // teper' X::h() imeet vnutrennee svyazyvanie
   {
     // ...
   }

   Specifikaciya virtual mozhet ispol'zovat'sya tol'ko v opisaniyah
nestaticheskih funkcij-chlenov pri opisanii klassa (sm. $$R.10.2).



Opisaniya so specifikaciej typedef zadayut identifikatory, kotorye
pozdnee mogut ispol'zovat'sya dlya oboznacheniya osnovnyh ili
proizvodnyh tipov. Specifikaciya typedef nedopustima v opredelenii-funkcii
($$R.8.3).
    imya-typedef:
          identifikator
V predelah oblasti vidimosti ($$R.3.2) opisaniya typedef lyuboj
identifikator, poyavlyayushchijsya v chasti lyubogo iz opisatelej,
stanovitsya sintaksicheski ekvivalentnym sluzhebnomu slovu i oboznachaet tip,
svyazannyj s dannym identifikatorom, kak opisano v $$R.8. Takim obrazom,
imya-typedef yavlyaetsya sinonimom drugogo tipa. V otlichie ot opisaniya
klassa ($$R.9.1) imya-typedef ne dobavlyaet novogo tipa. Naprimer,
posle opisaniya

        typedef int MILES, *KLICKSP;

konstrukcii

    MILES distance;
    extern KLICKSP metricp;

yavlyayutsya zakonnymi opisaniyami, tip distance est' int, a u metricp
tip "ukazatel' na int".
   S pomoshch'yu typedef mozhno pereopredelit' imya tak, chtoby ono opyat'
oboznachalo tip, na kotoryj uzhe ssylalos', prichem dazhe v toj oblasti
vidimosti, v kotoroj tip byl pervonachal'no opisan, naprimer,

     typedef struct s { /* ... */ } s;
     typedef int I;
     typedef int I;
     typedef I I;

  Bezymyannyj klass, kotoryj opredelyaetsya v typedef, poluchaet v
kachestve svoego imeni imya, ispol'zovannoe v typedef, naprimer,

     typedef struct { /* .... */ } S; // imya struktury stalo S

  S pomoshch'yu opisaniya typedef nel'zya pereopredelit' imya tipa,
opisannogo v etoj zhe oblasti vidimosti, tak, chtoby ono oboznachalo
drugoj tip, naprimer,

    class complex { /* ... */ };
    typedef int complex;   // oshibka: pereopredelenie

  Analogichno, nel'zya opisyvat' klass s imenem tipa, opisannogo
v etoj zhe oblasti vidimosti, tak, chtoby on oboznachal drugoj
tip, naprimer,

    typedef int complex;
    class complex { /* ... */ };  // oshibka: pereopredelenie

  Imya-typedef, kotoroe oboznachaet klass, yavlyaetsya imenem-klassa
($$R.9.1). Sinonim nel'zya ispol'zovat' posle sleduyushchih prefiksov:
class, struct i union, a takzhe v imenah konstruktorov i
destruktorov v opisanii samogo klassa, naprimer,

    struct S {
        S();
       ~S();
    };

    typedef struct S T;
    S a = T();    // normal'no
    struct T* p;  // oshibka





Specifikaciya shablona tipa ispol'zuetsya dlya zadaniya semejstva tipov
ili funkcij (sm. $$R.14).



Specifikaciya friend ispol'zuetsya dlya zadaniya dostupa k chlenam klassa
(sm. $$R.11.4).



K specifikacii tipa otnosyatsya:

     specifikaciya-tipa:
         imya-prostogo-tipa
         specifikaciya-klassa
         specifikaciya-perechisleniya
         specifikaciya-slozhnogo-tipa
         :: imya-klassa
         const
         volatile

Pri opisanii ob容kta sluzhebnye slova const i volatile mozhno dobavit'
k lyuboj zakonnoj specifikacii-tipa. Vo vseh drugih sluchayah v opisanii
mozhet prisutstvovat' ne bolee odnoj specifikacii-tipa. Ob容kt so
specifikaciej const mozhno inicializirovat', no ego znachenie ne
dolzhno izmenyat'sya v dal'nejshem. Ob容kt so specifikaciej const, esli
tol'ko on ne byl yavno opisan kak extern, ne podlezhit vneshnemu
svyazyvaniyu i dolzhen inicializirovat'sya ($$R.8.4, $$R.12.1). Celoe
so specifikaciej const, inicializirovannoe vyrazheniem-konstantoj,
mozhet ispol'zovat'sya v vyrazhenii-konstante ($$R.5.19). Kazhdyj
element massiva so specifikaciej const imeet tu zhe specifikaciyu,
a kazhdyj nestaticheskij chlen, ne yavlyayushchijsya funkciej, iz ob容kta klassa
so specifikaciej const sam schitaetsya const ($$R.9.3.1). Ob容kt tipa
bez konstruktora ili destruktora, kotoryj imeet specifikaciyu const,
mozhet byt' pomeshchen v pamyat', dostupnuyu tol'ko po chteniyu. Popytka
zapisi v lyubuyu chast' takogo ob容kta ili privedet k osoboj adresnoj
situacii, ili projdet bessledno, kak esli by ob容kt ne imel
specifikacii const.
    Ne sushchestvuet ne zavisyashchego ot realizacii ob座asneniya ob容ktov so
specifikaciej volatile. Ona sluzhit podskazkoj translyatoru izbegat'
slishkom aktivnoj optimizacii, svyazannoj s etim ob容ktom, poskol'ku
znachenie ob容kta mozhet izmenyat'sya sposobami, skrytymi ot
translyatora. Kazhdyj element massiva so specifikaciej volatile
imeet tu zhe specifikaciyu i kazhdyj nestaticheskij chlen, ne yavlyayushchijsya
funkciej, iz ob容kta klassa so specifikaciej volatile sam schitaetsya
volatile ($$R.9.3.1).
   Esli specifikaciya-tipa otsutstvuet v opisanii, ona schitaetsya
zadannoj kak int.

     imya-prostogo-tipa:
           polnoe-imya-klassa
           utochnennoe-imya-tipa
           char
           short
           int
           long
           signed
           unsigned
           float
           double
           void

Vmeste s int nel'zya zadavat' bolee odnogo sluzhebnogo slova long
ili short. Oni mogut ispol'zovat'sya i poodinochke, togda schitaetsya,
chto tip est' int. Sluzhebnoe slovo long mozhet poyavit'sya vmeste s
double. Vmeste s char, short, int ili long nel'zya zadavat' bolee
odnogo sluzhebnogo slova signed ili unsigned. Oni mogut
ispol'zovat'sya i poodinochke, togda schitaetsya, chto tip est' int.
Specifikaciya signed ukazyvaet, chto ob容kty tipa char i bitovye
polya yavlyayutsya znakovymi, dlya drugih celochislennyh tipov eta
specifikaciya izbytochna.
    Konstrukcii specifikaciya-klassa i specifikaciya-perechisleniya
opredelyayutsya v $$R.9 i $$R.7.2 sootvetstvenno.

     specifikaciya-slozhnogo-tipa:
           sluzhebnoe-slovo-klassa imya-klassa
           sluzhebnoe-slovo-klassa identifikator

     sluzhebnoe-slovo-klassa:
           class
           struct
           union

   Esli zadan identifikator, specifikaciya-slozhnogo-tipa opisyvaet
ego kak imya-klassa (sm. $$R.9.1).
   Esli opredeleno imya, kotoroe opisyvaetsya s pomoshch'yu specifikacii
union, to ono dolzhno byt' opredeleno kak ob容dinenie. Esli opredeleno
imya, kotoroe opisyvaetsya s pomoshch'yu specifikacii class, to ono dolzhno
byt' opredeleno s pomoshch'yu specifikacij class ili struct. Esli
opredeleno imya, kotoroe opisyvaetsya s pomoshch'yu specifikacii struct,
ono dolzhno byt' opredeleno s pomoshch'yu specifikacii class ili
struct. Imena vlozhennyh tipov ($$R.9.7) dolzhny utochnyat'sya imenem
ob容mlyushchego klassa:

          utochnennoe-imya-tipa:
               imya-typedef
               imya-klassa :: utochnennoe-imya-tipa

          polnoe-imya-klassa:
               utochnennoe-imya-klassa
               :: utochnennoe-imya-klassa

          utochnennoe-imya-klassa:
               imya-klassa
               imya-klassa :: utochnennoe-imya-klassa

Imya, utochnennoe imenem-klassa dolzhno byt' tipom, opredelennym v
etom klasse ili v bazovom klasse etogo klassa. Kak obychno, imya,
opisannoe v proizvodnom klasse, delaet nevidimymi chleny s etim
imenem iz bazovyh klassov (sm. $$R.3.2).



Perechislenie yavlyaetsya otdel'nym celochislennym tipom ($$R.3.6.1)
s konstantami-imenami. Ego imya v svoej oblasti vidimosti stanovitsya
konstrukciej imya-perechisleniya, t.e. sluzhit zarezervirovannym slovom.

          imya-perechisleniya:
              identifikator

          specifikaciya-perechisleniya:
              enum identifikator opt { spisok-perechisleniya }

          spisok-perechisleniya:
              element-perechisleniya
              spisok-perechisleniya , element-perechisleniya

          element-perechisleniya:
              identifikator
              identifikator = vyrazhenie-konstanta
Vse identifikatory iz spiska-perechisleniya schitayutsya opisannymi
kak konstanty i mogut poyavlyat'sya vsyudu, gde trebuyutsya konstanty.
Esli ne bylo elementov perechisleniya s =, to znacheniya konstant
nachinayutsya s nulya i posledovatel'no uvelichivayutsya na edinicu
po mere prodvizheniya v spiske sleva napravo. Esli element
perechisleniya vstretilsya s =, to ego identifikator prinimaet zadannoe
znachenie, a posleduyushchie identifikatory bez inicializiruyushchej chasti
budut poluchat' vozrastayushchie znacheniya, nachinaya s zadannogo. Znachenie
elementa perechisleniya dolzhno byt' tipa int ili znacheniem, kotoroe
mozhno privesti k int s pomoshch'yu standartnyh celochislennyh
preobrazovanij ($$R.4.1).
   Imena elementov perechisleniya dolzhny byt' otlichny ot imen obychnyh
peremennyh i drugih elementov perechisleniya toj zhe oblasti
vidimosti. Znacheniya elementov perechisleniya ne obyazany otlichat'sya
drug ot druga. Schitaetsya, chto element perechisleniya opisan s momenta
poyavleniya ego identifikatora ili inicializiruyushchego znacheniya,
(esli ono est'). Naprimer, v opredeleniyah

      enum { a, b, c=0 };
      enum { d, e, f=e+2 };

znacheniya a, c, i d zadany kak 0, b i e kak 1, a f kak 3.
    Kazhdoe perechislenie yavlyaetsya celochislennym tipom, kotoryj
otlichen ot vseh drugih celochislennyh tipov. Tipom elementa perechisleniya
schitaetsya dannoe perechislenie. Znachenie elementa perechisleniya ili
ob容kta tipa perechisleniya preobrazuetsya k celomu s pomoshch'yu
standartnyh celochislennyh preobrazovanij ($$R.4.1). Naprimer,
v sleduyushchem fragmente:

      enum color { red, yellow, green=20, blue };
      color col = red;
      color* cp = &col;
      if (*cp == blue ) // ...

color zadan kak celochislennyj tip, opisyvayushchij raznye cveta,
col opisan kak ob容kt etogo tipa, a cp kak ukazatel' na ob容kt
etogo tipa. Vozmozhnymi znacheniyami ob容kta tipa color yavlyayutsya
red, yellow, green, blue. |ti znacheniya mozhno preobrazovat'
v celye znacheniya 0, 1, 20 i 21. Poskol'ku kazhdoe perechislenie - eto
otdel'nyj tip, ob容ktu tipa color mozhno prisvaivat' tol'ko znacheniya
tipa color, naprimer,

    color c = 1;    // oshibka: nesootvetstvie tipov
                    // net preobrazovaniya ot int v color

    int i = yellow; // normal'no: yellow preobrazuetsya v int so znacheniem 1
                    // standartnoe celochislennoe preobrazovanie

Obratites' takzhe k $$R.18.3.
   |lementy perechisleniya, opredelennye v klasse ($$R.9), otnosyatsya
k oblasti vidimosti etogo klassa, i k nim mozhno obrashchat'sya izvne
funkcij-chlenov etogo klassa tol'ko s pomoshch'yu yavnogo utochneniya
imenem klassa ($$R.5.1). Imya samogo tipa perechisleniya lokal'no
v etom klasse ($$R.9.7), naprimer,

      class X {
      public:
          enum direction { left='l', right='r' };
          int f(int i)
              { return i==left ? 0 : i==right ? 1 : 2; }
      };

      void g(X* p)
      {
        direction d;        // oshibka: `direction' vne
        int i;              // oblasti vidimosti
        i = p->f(left);     // oshibka: `left' tozhe nevidim
        i = p->f(X::right); // normal'no
        // ...
      }



Opisanie asm imeet vid:

       opisanie-asm:
           asm ( stroka-literal) ;

Naznachenie opisaniya asm opredelyaetsya realizaciej. Obychno ono
ispol'zuetsya dlya peredachi informacii ot translyatora k assembleru.



S pomoshch'yu specifikacii-svyazi mozhno svyazat' ($$R.3.3) fragmenty
programm na S++ i na drugom yazyke:

     specifikaciya-svyazi:
         extern stroka-literal { spisok-opisanij opt }
         extern stroka-literal opisanie

     spisok-opisanij:
         opisanie
         spisok-opisanij opisanie

Trebuemoe svyazyvanie zadaetsya s pomoshch'yu stroki-literala. Ee naznachenie
opredelyaetsya realizaciej. No vo vseh realizaciyah dolzhno byt'
predusmotreno svyazyvanie s funkciej na yazyke S ("S") i s funkciej
na yazyke S++ ("S++"). Po umolchaniyu svyazyvanie zadaetsya kak "S++",
naprimer,

      complex sqrt(complex);   // po umolchaniyu svyazyvanie s C++
      extern "C" {
          double sqrt(double); // svyazyvanie s C
      }

   Specifikacii svyazi mogut byt' vlozhennymi. Specifikaciya svyazi
ne zadaet oblast' vidimosti. Specifikaciya-svyazi mozhet vstretit'sya
tol'ko v fajlovoj oblasti vidimosti ($$R.3.2). Specifikaciya-svyazi
dlya klassa otnositsya k ob容ktam, opisannym v nem, i funkciyam, ne
yavlyayushchimsya chlenami. Specifikaciya-svyazi, otnosyashchayasya k nekotoroj
funkcii, otnositsya i ko vsem ob容ktam i funkciyam, opisannym v nej.
Opisanie svyazi, soderzhashchee neizvestnuyu dlya realizacii stroku,
schitaetsya oshibochnym.
   Esli funkciya imeet bolee odnoj specifikacii-svyazi, to oni dolzhny
byt' soglasovany, t.e. zadavat' odnu i tu zhe stroku-literal.
Opisanie funkcii bez ukazaniya specifikacii-svyazi ne dolzhno
predshestvovat' pervomu ukazaniyu specifikacii svyazi dlya etoj funkcii.
Funkciya mozhet byt' opisana bez ukazaniya specifikacii svyazi dazhe
posle yavnogo ukazaniya specifikacii svyazi, no svyazyvanie, yavno zadannoe
v bolee rannem opisanii, ne budet ustraneno takim opisaniem funkcii.
   Iz mnozhestva peregruzhennyh funkcij ($$R.13) s dannym imenem
ne bolee odnoj mozhet imet' svyazyvanie s yazykom S, sm. $$R.7.4.
   Svyazyvanie mozhno ustanovit' dlya ob容ktov, naprimer:

     extern "C" {
        // ...
        _iobuf_iob[_NFILE];
        // ...
        int _flsbuf(unsigned,_iobuf*);
        // ...
     }

Kogda zadaetsya specifikaciya svyazi, to funkcii i ob容kty mozhno opisat' kak
staticheskie vnutri { }. Dlya takih funkcij ili ob容ktov komanda
svyazyvaniya ignoriruetsya. Inache, funkciya, opisannaya pri zadanii svyazi,
traktuetsya, kak esli by ona byla yavno opisana kak extern, naprimer,
nizhe vtoroe opisanie oshibochno ($$R.7.1.1):

     extern "C" double f();
     static double f();     // oshibka

Ob容kt, opisannyj vnutri konstrukcii

     extern "C" {  /* ... */ }

vse zhe schitaetsya opredelennym, a ne prosto opisannym.
    Svyazyvanie ob容ktov na S++ s ob容ktami, opredelennymi na drugih
yazykah, tak zhe kak i obratnoe svyazyvanie, zavisit ot yazykov i
realizacii. Takoe svyazyvanie vozmozhno tol'ko v tom sluchae, kogda
algoritmy razmeshcheniya ob容ktov v pamyati yavlyayutsya dostatochno shozhimi
dlya dvuh yazykov.
    Esli dlya zadaniya svyazi v stroke-literale iz specifikacii-svyazi
ispol'zuetsya imya yazyka programmirovaniya, to rekomenduetsya, chtoby
napisanie etogo imeni kopirovalos' iz dokumenta, opredelyayushchego dannyj
yazyk, naprimer, Ada (a ne ADA) i Fortran (a ne FORTRAN).



Spisok-opisatelej, figuriruyushchij v opisanii, - eto posledovatel'nost'
cherez zapyatuyu opisatelej, kazhdyj iz kotoryh mozhet imet'
inicializator.

      spisok-opisanij:
           opisatel'-s-inicializatorom
           spisok-opisanij , opisatel'-s-inicializatorom

      opisatel'-s-inicializatorom:
           opisatel' inicializator opt

Opisanie sostoit iz dvuh chastej: specifikacii (specifikaciya-opisaniya;
sm. $$R.7.1) i opisatelej (spisok-opisatelej). Specifikacii zadayut
osnovnoj tip, klass pamyati ili drugie svojstva opisyvaemyh ob容ktov
i funkcij. Opisateli zadayut imya etih ob容ktov i funkcij, a takzhe,
vozmozhno, izmenyayut tip s pomoshch'yu takih operacij, kak * (ukazatel' na)
i () (funkciya vozvrashchayushchaya). V opisatele takzhe mozhno zadat' nachal'nye
znacheniya, inicializaciya obsuzhdaetsya v $$R.8.4  i $$R.12.6.
    Opisateli imeyut takoj sintaksis:

    opisatel':
      imya-v-opisatele
      operaciya-ptr opisatel'
      opisatel' (spisok-opisanij-parametrov) spisok-specifikacij-cv opt
      opisatel' [ vyrazhenie-konstanta opt]
      ( opisatel' )

   operaciya-ptr:
      * spisok-specifikacij-cv opt
      & spisok-specifikacij-cv opt
      polnoe-imya-klassa :: * spisok-specifikacij-cv opt

   spisok-specifikacij-cv:
      const
      volatile

   imya-v-opisatele:
       imya
       imya-klassa
       ~imya-klassa
       imya-typedef
       utochnennoe-imya-tipa

Konstrukciya imya-klassa imeet opredelennoe naznachenie pri opisanii
klassa s etim imenem, ona zhe ispol'zuetsya kak utochnenie v operacii ::
dlya razresheniya kollizij v oblasti vidimosti ($$R.12.1, $$R.12.4).



Imya tipa neobhodimo ukazyvat' pri zadanii operacii yavnogo
preobrazovaniya tipa ili v kachestve parametra v operaciyah sizeof
ili new. Dlya etogo sluzhit konstrukciya imya-tipa, kotoraya sintaksicheski
ekvivalentna opisaniyu ob容kta ili funkcii etogo tipa, v kotorom
otsutstvuet imya ob容kta ili funkcii.

     imya-tipa:
       spisok-specifikacij-tipa abstraktnyj-opisatel' opt

     spisok-specifikacij-tipa:
       specifikaciya-tipa spisok-specifikacij-tipa

     abstraktnyj-opisatel':
       operaciya-ptr abstraktnyj-opisatel' opt

abstraktnyj-opisatel' opt ( spisok-opisanij-parametrov ) spisok-specifikacij cv opt
       abstraktnyj-opisatel' opt [ vyrazhenie-konstanta opt ]
       ( abstraktnyj-opisatel' )

Mozhno odnoznachno ukazat', v kakom meste abstraktnogo-opisatelya
nuzhno dobavit' identifikator, chtoby konstrukciya stala opisatelem,
dopustimym v opisanii. Togda poimenovannyj tip budet tem zhe, chto i
tip gipoteticheskogo identifikatora. Naprimer, opisaniya

        int             // int i
        int *           // int *pi
        int *[3]        // int *p[3]
        int (*)[3]      // int (*p3i)[3]
        int *()         // int *f()
        int (*)(double) // int (*pf)(double)

zadayut sootvetstvenno takie tipy: "celoe", "ukazatel' na celoe",
"massiv iz 3 ukazatelej na celoe", "ukazatel' na massiv iz 3 celyh",
"funkciya bez parametrov, vozvrashchayushchaya ukazatel' na celoe",
"ukazatel' na funkciyu s parametrom tipa double, vozvrashchayushchuyu celoe".



Neodnoznachnost', otmechennaya v $$R.6.8, kotoraya voznikaet iz-za shodstva
mezhdu privedeniem, zadannym v funkcional'nom stile, i opisaniem,
mozhet takzhe poyavit'sya v kontekste opisaniya. V etom kontekste ona
proyavlyaetsya kak shodstvo mezhdu opisaniem funkcii, v kotorom est'
izbytochnye skobki vokrug imeni parametra, i opisaniem ob容kta, v
kotorom v kachestve inicializatora ispol'zuetsya operaciya privedeniya,
zadannaya v funkcional'nom stile. Kak i dlya operatorov, neodnoznachnost'
ustranyaetsya pravilom, soglasno kotoromu sleduet schitat' opisaniem lyubuyu
konstrukciyu, kotoraya mozhet sluzhit' takovym. Mozhno yavno ustranit'
neodnoznachnost' v opisanii ili s pomoshch'yu privedeniya, zadannogo ne v
funkcional'nom stile, ili s pomoshch'yu operacii = dlya oboznacheniya
inicializacii, naprimer,

     struct S {
        S(int);
     };

    void foo(double a)
    {
      S x(int(a));   // opisanie funkcii
      S y((int)a);   // opisanie ob容kta
      S z = int(a);  // opisanie ob容kta
    }



Spisok opisatelej sleduet posle (vozmozhno pustogo) spiska
specifikacij-opisaniya ($$R.7.1). Kazhdyj opisatel' soderzhit v tochnosti
odno imya-iz-opisatelya, kotoroe zadaet opisyvaemyj identifikator.
Esli ne schitat' opisanij nekotoryh special'nyh funkcij ($$R.12.3,
$$R.13.4), imya-iz-opisatelya yavlyaetsya prosto identifikatorom.
Specifikacii auto, static, extern, register, friend, inline, virtual
ili typedef otnosyatsya neposredstvenno k kazhdomu imeni-iz-opisatelya iz
spiska opisatelej. Tip kazhdogo imeni-iz-opisatelya opredelyaetsya kak
specifikaciej-opisaniya ($$R.7.1), tak i ego opisatelem.
     Takim obrazom, opisanie nekotorogo identifikatora imeet vid

         T D

gde T oboznachaet tip, a D - opisatel'. Esli v opisanii D est'
identifikator bez skobok, to tip etogo identifikatora est' T.
     V opisanii, gde D imeet vid

         ( D1 )

tip D1 takoj zhe, kak i tip D. Nalichie skobok ne menyaet tipa zaklyuchennogo
v nih imeni-iz-opisatelya, no dlya slozhnyh opisatelej ono mozhet povliyat'
na poryadok primeneniya operacij.



V opisanii T D, v kotorom D imeet vid

      * spisok-specifikacij-cv opt D1

tip opisyvaemogo identifikatora est'
"... spisok-specifikacij-cv ukazatel' na T". Konstrukciya
spisok-specifikacij-cv otnositsya k ukazatelyu, a ne k ukazuemomu
ob容ktu.
   Naprimer, v opisaniyah

      const ci = 10, *pc = &ci, *const cpc = pc;
      int i *p, *const cp = &i;

opredelyayutsya: ci kak konstanta celoe; pc kak ukazatel' na konstantu
celoe; cpc kak konstanta ukazatel' na konstantu celoe; i kak celoe;
p kak ukazatel' na celoe; i cp kak konstanta ukazatel' na celoe.
Posle inicializacii znacheniya ci, cpc i cp ne mogut byt' izmeneny.
Znachenie pc mozhno izmenyat' tak zhe, kak i znachenie ob容kta, na kotoryj
ukazyvaet cp. Privedem primery dopustimyh operacij:

      i = ci;
      *cp = ci;
      pc++;
      pc = cpc;
      pc = p;

Nedopustimy sleduyushchie operacii:

      ci = 1;    // oshibka
      ci++;      // oshibka
      *pc = 2;   // oshibka
      cp = &ci;  // oshibka
      cpc++;     // oshibka
      p = pc;    // oshibka

Kazhdaya iz etih operacij nedopustima ili potomu, chto ona izmenyaet znachenie
ob容kta, opisannogo so specifikaciej const, ili potomu, chto delaet
takoe izmenenie vozmozhnym pozdnee s pomoshch'yu ukazatelya, nastroennogo
na ob容kt bez specifikacii const.
    Analogichna situaciya so specifikaciej volatile.
    Obratites' k $$R.5.17 i $$R.8.4.
    Nel'zya opisyvat' ukazateli na ssylki ($$R.8.2.2) ili ukazateli
na bitovye polya ($$R.9.6).



V opisanii T D, v kotorom D imeet vid

    & spisok-specifikacij-cv opt D1

tip opisyvaemogo identifikatora est'
"...spisok-specifikacij-cv ssylka na T". Tip void& nedopustim.
    Naprimer, vo fragmente

    void f(double& a) { a += 3.14; }
    // ...
       double d = 0;
       f(d);

a opisyvaetsya kak parametr, yavlyayushchijsya ssylkoj, poetomu vyzov
f(d) privedet k uvelicheniyu d na 3.14. Vo fragmente

    int v[20];
    // ...
    int& g(int i) { return v[i]; }
    // ...
    g(3) = 7;

opisyvaetsya: funkciya g() vozvrashchaet ssylku na celoe; poetomu
operator g() = 7; prisvoit 7 chetvertomu elementu massiva v.
Rassmotrim sleduyushchij programmnyj fragment:

   struct link {
      link* next;
   };
   link* first;

   void h(link*& p)  // `p' ssylka na ukazatel'
   {
     p->next = first;
     first = p;
     p = 0;
   }

   void k()
   {
     link* q = new link;
     h(q);
   }

Zdes' p opisano kak ssylka na ukazatel' na link, poetomu vyzov h(q)
ne izmenit znachenie q, ravnoe 0, sm. takzhe $$R.8.4.3.
   Nedopustimy ssylki na ssylki, ssylki na bitovye polya ($$R.9.6),
massivy ssylok i ukazateli na ssylki. Opisanie ssylki dolzhno soderzhat'
inicializator ($$R.8.4.3), za isklyucheniem teh sluchaev, kogda opisanie
soderzhit yavnuyu specifikaciyu extern ($$R.7.1.1), ili yavlyaetsya opisaniem
chlena klassa ($$R.9.2) pri opisanii samogo klassa, ili yavlyaetsya
opisaniem parametra ili vozvrashchaemogo tipa ($$R.8.2.5),
sm. takzhe $$R.3.1.



V opisanii T D, v kotorom D imeet vid
    polnoe-imya-klassa :: * spisok-specifikacij-cv opt D1
tip opisyvaemogo identifikatora est'
"... spisok-specifikacij-cv ukazatel' na chlen klassa polnoe-imya-klassa tipa T".
Naprimer, vo fragmente

     class X {
     public:
        void f(int);
        int a;
     };

     int X::* pmi = &X::a;
     void (X::* pmf)(int) = &X::f;

pmi i pmf opisyvayutsya kak ukazatel' na chlen X tipa T i ukazatel' na
chlen X tipa void(int) sootvetstvenno. |ti ob容kty mozhno ispol'zovat'
tak:

    X obj;
    // ...
    obj.*pmi = 7;   // prisvoit' 7 chlenu obj tipa int
    (obj.*pmf)(7);  // vyzvat' funkciyu-chlen obj
                    // s parametrom 7

   Otmetim, chto ukazatel' na chlen nel'zya nastroit' na staticheskij
chlen klassa ($$R.9.4), sm. takzhe $$R.5.5 i $$R.5.3.



V opisanii T D, v kotorom D imeet vid

    D1 [ vyrazhenie-konstanta opt ]

opisyvaetsya identifikator tipa " ... massiv T". Esli
vyrazhenie-konstanta prisutstvuet ($$R.5.19), to ono dolzhno imet'
celochislennyj tip i znachenie, bol'shee 0. |to vyrazhenie zadaet chislo
elementov massiva. Esli znachenie vyrazheniya-konstanty est' N, to
massiv imeet N elementov s indeksami ot 0 do N-1.
   Massiv mozhno obrazovyvat' iz: odnogo iz osnovnyh tipov (za isklyucheniem
void), ukazatelya, ukazatelya na chleny, klassa, perechisleniya ili iz
drugogo massiva.
   Esli podryad idut neskol'ko specifikacij "massiv ...", obrazuetsya
mnogomernyj massiv, prichem vyrazhenie-konstanta, zadayushchee granicy
massiva, mozhet otsutstvovat' tol'ko dlya pervogo massiva. Takoe umolchanie
polezno v sluchae parametrov funkcii tipa massiv, a takzhe kogda massiv
yavlyaetsya vneshnim, a ego opredelenie, s kotorym svyazano rezervirovanie
pamyati, nahoditsya v drugom meste. Pervoe vyrazhenie-konstanta mozhet
byt' propushcheno i v tom sluchae, esli za opisatelem sleduet
spisok-inicializatorov ($$R.8.4). Togda razmer massiva opredelyaetsya
chislom elementov, privedennyh v inicializatore ($$R.8.4.1).
    V opisanii

        float fa[17], *afp[17];

opisany massiv chisel tipa float i massiv ukazatelej na chisla tipa float,
a v opisanii

        static int x3d[3][5][7];

opisan staticheskij trehmernyj massiv celyh razmera 3x5x7. Strogo
govorya, x3d yavlyaetsya massivom iz treh elementov, kazhdyj iz kotoryh
est' massiv iz pyati massivov, a kazhdyj iz poslednih yavlyaetsya massivom
iz semi celyh. V vyrazhenii dopustimo poyavlenie lyubogo iz sleduyushchih
vyrazhenij: x3d, x3d[i], x3d[i][j], x3d[i][j][k].
    Esli v vyrazhenii uchastvuet identifikator tipa massiv, to, isklyuchaya
sluchai operanda v operaciyah sizeof ili & i inicializatora dlya
ssylki ($$R.8.4.3), ego tip preobrazuetsya v ukazatel' na pervyj
element massiva. Nesmotrya na eto preobrazovanie, massivy ne yavlyayutsya
izmenyaemymi adresami. Esli ne schitat' sluchaj ispol'zovaniya massiva
pri opisanii klassa ($$R.13.4.5), operaciya indeksacii opredelyaetsya
tak, chto E1[E2] sovpadaet s *((E1) + (E2)). S uchetom pravil
preobrazovaniya tipov dlya operacii +, esli E1 est' massiv, a E2
celoe, to E1[E2] ukazyvaet na E2-element iz E1. Poetomu, nesmotrya
na svoj asimetrichnyj vid, indeksaciya - kommutativnaya operaciya.
    Analogichnoe pravilo dejstvuet i dlya mnogomernyh massivov. Esli
E - n-mernyj massiv razmera ixjx...xk, to v vyrazhenii on
preobrazuetsya v ukazatel' na (n-1)-mernyj massiv razmera jx...xk.
Esli k etomu ukazatelyu yavno ili neyavno v rezul'tate indeksacii primenyaetsya
operaciya *, ukazuemyj (n-1)-mernyj massiv sam nemedlenno preobrazuetsya
v ukazatel'.
    Naprimer, rassmotrim opisanie

    int x[3][5];

Zdes' opisan massiv iz 3x5 celyh. Esli v vyrazhenii poyavlyaetsya x, to
ono preobrazuetsya v ukazatel' na pervyj massiv iz pyati celyh.
Esli v vyrazhenii poyavlyaetsya x[i], chto ekvivalentno *(x+i), v nachale
x preobrazuetsya v ukazatel', kak bylo skazano vyshe, zatem x+i
preobrazuetsya k tipu x, dlya chego neobhodimo i umnozhit' na razmer ob容kta,
na kotoryj ukazyvaet x, t.e. na razmer pyati celyh. Zatem proishodit
slozhenie i primenyaetsya kosvennost', posle chego poluchim massiv (iz pyati
celyh), kotoryj v svoyu ochered' preobrazuetsya v ukazatel' na pervoe iz
celyh. Esli est' eshche odna indeksaciya, process povtoryaetsya, i na etot raz
my poluchim v rezul'tate celoe.
   Iz vsego etogo sleduet, chto massivy V S++ hranyatsya po strokam
(poslednij indeks izmenyaetsya bystree vsego), a znachenie pervogo
indeksa iz opisaniya pozvolyaet vychislit' razmer pamyati, neobhodimoj
dlya massiva, odnako pri vychislenii indeksnogo vyrazheniya pervyj indeks
roli ne igraet.



V opisanii T D, v kotorom D imeet vid

   D1 (spisok-opisanij-parametrov ) spisok-specifikacij-cv opt

opisyvaemyj identifikator imeet tip
"...spisok-specifikacij-cv funkciya s parametrami tipa
spisok-opisanij-parametrov vozvrashchayushchaya T".

   spisok-opisanij-parametrov:
        spisok-opisanij-param opt ... opt
        spisok-opisanij-param , ...

   spisok-opisanij-param:
        opisanie-parametra
        spisok-opisanij-param , opisanie-parametra

   opisanie-parametra:
        specifikacii-opisaniya opisatel'
        specifikacii-opisaniya opisatel' = vyrazhenie
        specifikacii-opisaniya abstraktnyj-opisatel' opt
        specifikacii-opisaniya abstraktnyj-opisatel' opt = vyrazhenie

   Esli spisok-opisanij-parametrov zavershaetsya ellipsisom (...),
pro chislo parametrov izvestno tol'ko to, chto ono bol'she ili ravno
chisla zadannyh parametrov, esli spisok parametrov pust, to funkciya
parametrov ne imeet. Spisok parametrov void ekvivalenten pustomu
spisku parametrov. Ne schitaya etogo sluchaya, void ne mozhet byt' tipom
parametra (hotya tipy, poluchaemye iz void, takie kak void*, dopustimy).




Opredeleniya funkcij imeyut vid

  opredelenie-funkcii:
specifikacii-opisaniya opt opisatel' inicializator-ctor telo-funkcii

  telo-funkcii:
     sostavnoj-operator

Konstrukciya opisatel' iz opredeleniya-funkcii dolzhna soderzhat' opisatel'
vida

     D1 ( spisok-opisanij-parametrov ) spisok-specifikacij-cv  opt

v sootvetstvii s opredeleniyami iz $$R.8.2.5
     Formal'nye parametry otnosyatsya k oblasti vidimosti samogo
bol'shogo bloka tela-funkcii.
    Privedem primer polnogo opredeleniya funkcii.

      int max( int a, int b, int c)
      {
        int m = (a > b) ? a : b;
         return (m > c) ? m : c;
      }

Zdes' int predstavlyaet specifikacii-opisaniya, max(int a, int b, int c)
- opisatel', a { /* ... */ } - telo-funkcii.
   Konstrukciya inicializator-ctor ispol'zuetsya tol'ko v konstruktorah,
sm. $$R.9.3.1 i $$R.12.6.
   Konstrukciya spisok-specifikacij-cv mozhet uchastvovat':
v opisanii nestaticheskoj funkcii-chlena, v opredelenii nestaticheskoj
funkcii-chlena ili v opisanii ukazatelya na funkciyu-chlen, sm. $$R.9.3.1.
Ona otnositsya k tipu funkcii.
   Otmetim, chto neispol'zuemym formal'nym parametram imena mozhno
ne davat', naprimer,

     void print(int a, int)
     {
       printf("a = %d\n",a);
     }



Za opisatelem mozhet idti nachal'noe znachenie opisyvaemogo identifikatora.

   inicializator:
         = vyrazhenie-prisvaivaniya
         = { spisok-inicializatorov , opt }
         ( spisok-vyrazhenij )

   spisok-inicializatorov:
         vyrazhenie-prisvaivaniya
         spisok-inicializatorov , vyrazhenie-prisvaivaniya
         { spisok-inicializatorov , opt }

  Avtomaticheskie, registrovye, staticheskie i vneshnie peremennye
mozhno inicializirovat' proizvol'nymi vyrazheniyami, soderzhashchimi
konstanty i opisannye ranee peremennye i funkcii.

     int f(int);
     int a = 2;
     int b = f(a);
     int c(b);

  Ukazatel' tipa const T*, t.e. ukazatel' na konstantu T, mozhet
inicializirovat'sya ukazatelem tipa T*, no inicializaciya dlya ukazatelej
v obratnom poryadke nezakonna. Ob容kty tipa T mozhno inicializirovat'
ob容ktami tipa T nezavisimo ot ispol'zovaniya specifikacij const ili
volatile v tipah inicializiruemoj peremennoj ili inicializatora,
naprimer,

     int a;
     const int b = a;
     int c = b;

     const int* p0 = &a;
     const int* p1 = &b;
     int* p2 = &b;        // oshibka: ukazatel' bez const
                          // nastraivaetsya na ob容kt const
     int *const p3 = p2;
     int *const p4 = p1;  // oshibka: ukazatel' bez const
                          // nastraivaetsya na ob容kt const
     const int* p5 = p1;

Zdes' prichina obeih oshibok odna: esli dopustit' podobnuyu inicializaciyu,
ona pozvolit izmenyat' s pomoshch'yu ukazatelya bez sootvetstvuyushchej
specifikacii znachenie chego-to, chto bylo opisano kak const.
   Na vyrazheniya dlya standartnyh znachenij parametrov nakladyvaetsya
bol'she ogranichenij, sm. $$R.8.2.6.
  Inicializaciya ob容ktov klassov s pomoshch'yu konstruktorov opisyvaetsya
v $$R.12.6.1. Kopirovanie ob容ktov klassov opisyvaetsya v $$R.12.8.
Poryadok inicializacii staticheskih ob容ktov opredelyaetsya v $$R.3.4
i $$R.6.7.
  Garantiruetsya, chto peremennye staticheskogo klassa pamyati ($$R.3.5),
kotorye ne byli inicializirovany, v kachestve nachal'nogo znacheniya
poluchat 0, privedennyj k nuzhnomu tipu. To zhe spravedlivo dlya staticheskih
chlenov ob容ktov klassa. Nachal'nye znacheniya avtomaticheskih i
registrovyh peremennyh, kotorye ne byli inicializirovany, neopredeleny.
  Esli inicializator otnositsya k ukazatelyu ili ob容ktu arifmeticheskogo
tipa, on sostoit iz odnogo vyrazheniya (vozmozhno v skobkah). V kachestve
nachal'nogo znacheniya ob容kta beretsya znachenie vyrazheniya, proishodyat
takie zhe preobrazovaniya tipa, kak i v sluchae prisvaivaniya.
  Zametim, chto poskol'ku () ne yavlyaetsya inicializatorom,
opisanie

    X a();

zadaet ne ob容kt a tipa klass X, a yavlyaetsya opisaniem funkcii bez
parametrov, vozvrashchayushchej X.
   Inicializator dlya staticheskogo chlena prinadlezhit oblasti
vidimosti chlena klassa, naprimer,

      int a;

      struct X {
         static int a;
         static int b;
      };

      int X::a = 1;
      int X::b = a;  // X::b = X::a



Agregatom nazyvaetsya massiv ili ob容kt tipa klass ($$R.9), ne imeyushchij
konstruktorov ($$R.12.1), chastnyh ili zashchishchennyh chlenov ($$R.11),
bazovyh klassov ($$R.10) i virtual'nyh funkcij ($$R.10.2). Esli
agregat inicializiruetsya, to inicializatorom dolzhen byt'
spisok-inicializatorov, kotoryj sostoit iz zaklyuchennogo v figurnye
skobki spiska, razdelennogo zapyatymi, inicializatorov dlya chlenov
agregata. Inicializatory idut v vozrastayushchem poryadke indeksov ili
chlenov agregata. Esli agregat soderzhit vlozhennye agregaty, eto
pravilo primenyaetsya rekursivno dlya chlenov vlozhennyh agregatov. Esli
inicializatorov v spiske men'she, chem chlenov agregata, to on
dopolnyaetsya nulevymi znacheniyami sootvetstvuyushchih tipov.
    Naprimer, v sleduyushchem fragmente

       struct S { int a; char* b; int c; }
       S ss = { 1, "asdf" };

ss.a inicializiruetsya znacheniem 1, ss.b - "asdf", a ss.c - 0.
    Krome togo, agregat, yavlyayushchijsya klassom, mozhno inicializirovat'
ob容ktom etogo klassa ili klassa, yavlyayushchegosya obshchim proizvodnym
ot nego ($$R.12.8).
    Figurnye skobki razbirayutsya sleduyushchim obrazom. Esli
spisok-inicializatorov nachinaetsya levoj figurnoj skobkoj, to
spisok inicializatorov, razdelennyh zapyatymi, zadaet
znacheniya chlenam agregata, prichem schitaetsya oshibkoj, esli
inicializatorov bol'she, chem chlenov. Inache, esli spisok-inicializatorov
ili vlozhennyj agregat ne nachinaetsya levoj figurnoj skobkoj, to
iz spiska ispol'zuetsya takoe chislo elementov, kotoroe nuzhno dlya
inicializacii chlenov tekushchego agregata; vse ostavshiesya elementy
ispol'zuyutsya dlya inicializacii chlenov sleduyushchego agregata, v kotoryj
vlozhen tekushchij agregat.
   Naprimer, v opredelenii

       int x[] = { 1, 3, 5 };

massiv x inicializiruetsya kak odnomernyj massiv iz treh elementov,
poskol'ku razmer massiva ne ukazan, i privedeno tri inicializatora.
   Privedem primer inicializacii s polnoj skobochnoj strukturoj.

       float y[4][3] = {
          { 1, 3, 5 },
          { 2, 4, 6 },
          { 3, 5, 7},
       };

Zdes' znacheniya 1, 3, 5 inicializiruyut pervuyu stroku massiva y[0],
t.e. y[0][0], y[0][1] i y[0][2]. Analogichno, sleduyushchie dve stroki
inicializiruyut y[1] i y[2]. Inicializatory privedeny ne polnost'yu,
poetomu y[3] inicializiruetsya nulyami. Tochno takogo zhe rezul'tata
mozhno dostich' s pomoshch'yu takoj inicializacii:

       float y[4][3] = {
          1, 3, 5, 2, 4, 6, 3, 5, 7,
       };

Poslednij (samyj pravyj) indeks izmenyaetsya bystree vsego.
    V poslednem primere inicializator dlya y nachinaetsya levoj figurnoj
skobkoj, no dlya y[0] skobki ne zadano, poetomu iz spiska ispol'zuetsya
tri elementa, takzhe po tri posledovatel'nyh elementa ispol'zuetsya dlya
y[1] i y[2]. V sleduyushchem primere

       float y[4][3] = {
       { 1 }, { 2 }, { 3 }, { 4 }
       };

inicializiruetsya pervyj stolbec y (kotoryj rassmatrivaetsya kak
dvumernyj massiv), a ostal'nye stolbcy prinimayut znachenie 0.
     Inicializaciya massiva ob容ktov tipa klass s pomoshch'yu konstruktorov
opisyvaetsya v $$R.12.6.1.
     Inicializator dlya ob容dineniya bez konstruktora dolzhen byt'
ili otdel'nym vyrazheniem tipa ob容dineniya, ili zaklyuchennym v figurnye
skobki, inicializatorom pervogo chlena ob容dineniya, naprimer,

       union u { int a; char* b; };

       u a = { 1 };
       u b = a;
       u c = 1;             // oshibka
       u d = { 0, "asdf" }; // oshibka
       u e = { "asdf" };    // oshibka

    CHislo inicializatorov ne dolzhno prevyshat' chisla chlenov ili
elementov, kotorye inicializiruyutsya. Naprimer, sleduyushchaya
inicializaciya oshibochna:

       char cv[4] = { 'a', 's', 'd', 'f', 0 };  // oshibka



Massiv simvolov (nevazhno, znakovyh ili bezznakovyh) mozhno
inicializirovat' strokoj-literalom: simvoly stroki posledovatel'no
inicializiruyut elementy massiva. Sleduyushchee opredelenie daet primer
simvol'nogo massiva, elementy kotorogo inicializiruyutsya strokoj:

       char msg[] = "Syntax error on line %s\n";

Zametim, chto poskol'ku '\n' zadaet odin simvol, i poskol'ku dobavlyaetsya
zavershayushchij simvol '\0', sizeof(msg) ravno 25.
    Nel'zya zadavat' bol'she inicializatorov, chem est' elementov v massive,
poetomu sleduyushchij primer oshibochen: zdes' net mesta dlya podrazumevayushchegosya
simvola konca stroki ('\0'):

       char cv[4] = "asdf";  // oshibka



Peremennaya, opisannaya kak T&, t.e. "ssylka na tip T" ($$R.8.2.2),
dolzhna inicializirovat'sya ob容ktom tipa T ili ob容ktom, kotoryj
mozhno preobrazovat' k tipu T, naprimer,

       void f()
       {
         int i;
         int& r = i;  // `r' ssylaetsya na `i'
         r = 1;       // `i' prinimaet znachenie 1
         int* p = &r; // `p' ukazyvaet na `i'
         int& rr = r; // `rr' ssylaetsya na to, na chto ssylalos' `r',
                      //  t.e. na `i'
       };

   Ssylku posle inicializacii nel'zya izmenyat' tak, chtoby ona
oboznachala drugoj ob容kt. Otmetim, chto inicializaciya ssylki
traktuetsya sovsem ne tak, kak prisvaivanie ssylke. Peredacha
parametra ($$R.5.2.2) i operaciya vozvrata znacheniya funkcii ($$R.6.6.3)
schitayutsya inicializaciej.
   Inicializator dlya ssylki mozhno opuskat' tol'ko v opisanii
parametra ($$R.8.2.5), v opisanii vozvrashchaemogo funkciej tipa,
v opisanii chlena klassa pri opisanii samogo klassa ($$R.9.2) i tam,
gde yavno ispol'zovana specifikaciya extern, naprimer,

       int& r1;        // oshibka: net inicializacii
       extern int& r2; // normal'no

   Esli inicializator dlya ssylki na tip T yavlyaetsya adresom tipa T
ili tipom, proizvodnym ot T ($$R.10), dlya kotorogo T sluzhit
dostupnym bazovym tipom ($$R.4.6), ssylka budet oboznachat' znachenie,
zadannoe inicializatorom. Inache, v tom i tol'ko tom sluchae, kogda
ssylka oboznachaet ob容kt so specifikaciej const, budet sozdan ob容kt
tipa T  i proinicializirovan znacheniem, zadannym inicializatorom.
Teper' ssylka igraet rol' imeni etogo ob容kta, naprimer,

        double d = 1.0;

        double& rd = d;        // rd ssylaetsya na `d'
        const double& rcd = d; // rcd ssylaetsya na `d'

        double& rd2 = 1;       // oshibka: nesootvetstvie tipa
        const double& rcd2 = 1;// rcd2 ssylaetsya na vremennyj ob容kt
                               // so znacheniem `1'

   Ssylku na volatile T mozhno inicializirovat' ob容ktom tipa
volatile T ili prosto T, no ne const T. Ssylku na const T mozhno
inicializirovat' const T, prosto T ili chem-to, chto mozhno preobrazovat'
v tip T, no ne volatile T. Ssylku na tip T (bez const ili volatile)
mozhno inicializirovat' tol'ko ob容ktom tipa T.
   Vremya zhizni vremennogo ob容kta, sozdannogo pri opisannoj
inicializacii, opredelyaetsya tekushchej oblast'yu vidimosti, v kotoroj
on byl sozdan ($$R.3.5). Otmetim, chto ssylku na klass B mozhno
inicializirovat' ob容ktom klassa D pri uslovii, chto V yavlyaetsya
odnoznachno opredelennym i dostupnym bazovym klassom dlya D (togda
govoryat, chto "D est' B"), sm. $$R.4.7.



Klass est' tip. Ego imya ispol'zuetsya kak imya-klassa ($$R.9.1), t.e.
stanovitsya zarezervirovannym slovom v ego oblasti vidimosti.

       imya-klassa:
           identifikator

Dlya obrazovaniya konstrukcii imya-klassa ispol'zuyutsya specifikacii-klassa
i specifikacii-slozhnogo-tipa ($$R.7.1.6). Ob容kt klassa sostoit iz
posledovatel'nosti (vozmozhno pustoj) chlenov.

    specifikaciya-klassa:
      zagolovok-klassa { spisok-chlenov opt }

    zagolovok-klassa:
      sluzhebnoe-slovo-klassa identifikator opt spec-bazovyh opt
      sluzhebnoe-slovo-klassa imya-klassa spec-bazovyh opt

    sluzhebnoe-slovo-klassa:
       class
       struct
       union

   Imya klassa mozhno ispol'zovat' v kachestve konstrukcii imya-klassa
dazhe v spiske-chlenov samogo etogo klassa. Obychno specifikaciyu-klassa
nazyvayut opisaniem klassa. Klass schitaetsya opredelennym, kak tol'ko
poyavitsya specifikaciya-klassa, nesmotrya na to, chto ego funkcii-chleny
mogut byt' eshche neopredeleny.
   Ob容kty pustogo klassa imeyut nenulevoj razmer.
   Ob容kty tipa klass mozhno prisvaivat', peredavat' v kachestve
parametrov funkcij i poluchat' v kachestve znacheniya, vozvrashchaemogo
funkciej (za isklyucheniem ob容ktov teh klassov, dlya kotoryh kopirovanie
ogranicheno, sm. $$R.12.8). Drugie vozmozhnye operacii, takie, kak
sravnenie na ravenstvo, mogut opredelyat'sya pol'zovatelem, sm. $$R.13.4.
    Strukturoj nazyvaetsya klass, opisannyj so sluzhebnym-slovom-klassa
struct; ee chleny i bazovye klassy ($$R.10) schitayutsya obshchimi po
opredeleniyu ($$R.11). Ob容dineniem nazyvaetsya klass, opisannyj so
sluzhebnym-slovom-klassa union; ego chleny schitayutsya obshchimi po
opredeleniyu, i v lyuboj moment vremeni ob容dinenie soderzhit tol'ko
odin chlen ($$R.9.5).



Opisanie klassa porozhdaet novyj tip. Naprimer, nizhe opisyvayutsya
tri peremennye treh razlichnyh tipov:

      struct X { int a; };
      struct Y { int a; };
      X a1;
      Y a2;
      int a3;

Otsyuda sleduet, chto takie prisvaivaniya privodyat k nesootvetstviyu
tipov:

      a1 = a2;   // oshibka: Y prisvaivaetsya X
      a1 = a3;   // oshibka: int prisvaivaetsya X

Nizhe opisyvaetsya peregruzka ($$R.13) funkcii f(), a ne prosto
povtornoe opisanie toj zhe funkcii:

      int f(X);
      int f(Y);

Po toj zhe prichine nel'zya dvazhdy opredelyat' klass, eto vidno iz
primera nizhe, gde dvazhdy opredelen S:

      struct S { int a; };
      struct S { int a; };  // oshibka, povtornoe opredelenie

   Opisanie klassa vklyuchaet imya klassa v tu oblast' vidimosti, vnutri
kotoroj ono proizoshlo, i zakryvaet lyuboj klass, ob容kt, funkciyu ili
drugoe opisanie etogo imeni v ob容mlyushchej oblasti vidimosti ($$R.3.2).
Esli imya klassa opisano v takoj oblasti vidimosti, gde uzhe byl
opisan ob容kt s takim zhe imenem, funkciya ili element perechisleniya, to
obrashchat'sya k klassu mozhno tol'ko s pomoshch'yu konstrukcii
specifikaciya-slozhnogo-tipa ($$R.7.1.6), naprimer:

      struct stat {
         // ...
      };

      stat gstt;              // prosto `stat' ispol'zuetsya dlya
                              // opredeleniya peremennoj
      int stat(struct stat*); // pereopredelenie `stat' kak funkcii

      void f()
      {
         struct stat* ps;     // nuzhen prefiks struct
                              // dlya zadaniya struktury stat
         // ...
         stat(ps);            // vyzov stat()
         // ...
      }

Konstrukciya specifikaciya-slozhnogo-tipa vmeste so
sluzhebnym-slovom-klassa, no bez opisaniya ob容kta ili funkcii takzhe
mozhet sluzhit' dlya zadaniya imeni klassa, kak i opisanie klassa, odnako
v etom sluchae klass ne schitaetsya opredelennym, naprimer:

      struct s { int a; };

      void g()
      {
        struct s;  // skryvaet global'nuyu strukturu `s'
        s* p;      // ispol'zuetsya lokal'naya struktura `s'
        struct s { char* p; };  // opisanie lokal'noj struktury `s'
      }

Takie pravila pozvolyayut klassam ssylat'sya drug na druga pri ih
opisanii, primer,

      class vector;

      class matrix {
          // ...
          friend vector operator*(matrix&, vector&);
      };

     class vector {
         // ...
          friend vector operator*(matrix&, vector&);
     };

Opisanie friend (druzhestvennye funkcii) obsuzhdaetsya v $$R.11.4, a
funkciya operator v $$R.13.4. Esli klass, ukazannyj kak drug, poka
eshche ne opisan, ego imya schitaetsya prinadlezhashchim toj zhe oblasti
vidimosti, v kotoroj nahoditsya imya klassa, soderzhashchego opisanie
friend ($$R.11.4).
    V opisanii ob容ktov ili funkcij mozhno takzhe ispol'zovat'
konstrukciyu specifikaciya-slozhnogo-tipa ($$R.7.1.6). Ee ispol'zovanie
otlichaetsya ot opisaniya klassa tem, chto esli klass, ch'e imya ukazano
v specifikacii, nahoditsya v tekushchej oblasti vidimosti, to imya iz
etoj specifikacii budet ssylat'sya na nego, naprimer:

      struct s { int a; }

      void g()
      {
         struct* s p = new s;  // obrashchenie k global'noj `s'
         p->a = 1;
      }

  Imya schitaetsya opisannym srazu zhe posle poyavleniya ego identifikatora
v opisanii. Otsyuda sleduet, chto v opisanii

      class A * A;

A v nachale zadaetsya, kak imya klassa, a zatem ono pereopredelyaetsya
kak imya ukazatelya na ob容kt etogo klassa, poetomu dlya oboznacheniya etogo
klassa sleduet ispol'zovat' specifikaciyu-slozhnogo tipa class A. Takoe
"tryukachestvo" s imenami mozhet vyzvat' nedoumenie, i luchshe ego izbegat'.
 Konstrukciya imya-typedef ($$R.7.1.3) oboznachaet klass i schitaetsya
imenem-klassa, sm. takzhe $$R.7.1.3.



   spisok-chlenov:
      opisanie-chlena spisok-chlenov opt
      specifikaciya-dostupa : spisok-chlenov opt

   opisanie-chlena:
      specifikacii-opisaniya opt spisok-opisatelej-chlenov opt ;
      opredelenie-funkcii ; opt
      utochnennoe-imya ;

   spisok-opisatelej-chlenov:
      opisatel'-chlena
      spisok-opisatelej-chlenov , opisatel'-chlena

   opisatel'-chlena:
      opisatel' specifikaciya-chistoj opt
      identifikator opt : vyrazhenie-konstanta

   specifikaciya-chistoj:
      = 0

  S pomoshch'yu konstrukcii spisok-chlenov mozhno opisat' dannye, funkcii,
klassy, elementy perechisleniya ($$R.7.2), bitovye polya, druzej
($$R.11.4) i imena tipov ($$R.7.1.3, $$R.9.1). Krome togo,
spisok-chlenov mozhet soderzhat' opisaniya, ustanavlivayushchie dostup k
imenam chlenov, sm. $$R.11.3. Nikakoj chlen ne mozhet byt' dvazhdy
opisan v spiske-chlenov. Spisok-chlenov opredelyaet vse mnozhestvo
chlenov dannogo klassa, t.e. nel'zya dobavit' eshche odin chlen v kakom-libo
drugom opisanii.
    Otmetim, chto odno imya mozhet oboznachat' neskol'ko funkcij-chlenov
pri uslovii, chto ih tipy dostatochno otlichayutsya drug ot druga ($$R.13).
Ukazhem, chto opisatel'-chlena ne mozhet soderzhat' inicializatora ($$R.8.4).
Inicializaciya chlena vozmozhna s pomoshch'yu konstruktora, sm. $$R.12.1.
    CHlen ne mozhet imet' specifikaciyu auto, extern ili register.
    Konstrukciya specifikacii-opisaniya mozhet otsutstvovat' tol'ko v
opisanii funkcii. Konstrukciya spisok-opisatelej-chlenov mozhet
opuskat'sya tol'ko posle konstrukcij specifikaciya-klassa,
specifikaciya-perechisleniya ili specifikaciya-opisaniya, esli poslednyaya
imeet vid friend specifikaciya-slozhnogo-tipa. Konstrukciya
specifikaciya-chistoj ispol'zuetsya tol'ko pri opisanii virtual'noj
funkcii ($$R.10.2).
    Esli chleny yavlyayutsya ob容ktami klassov, to eti klassy dolzhny
byt' ranee opisany. V chastnosti, klass C1 ne mozhet soderzhat' ob容kt
klassa C1, no mozhet soderzhat' ukazatel' ili ssylku na klass C1.
Esli v tipe nestaticheskogo chlena ispol'zuetsya massiv, to vse
razmery vseh indeksov massiva dolzhny byt' ukazany.
    Privedem prostoj primer opisaniya klassa:

    struct tnode {
        char tword[20];
        int count;
        tnode *left;
        tnode *right;
    };

Zdes' klass soderzhit massiv iz dvadcati simvolov, celoe i dva
ukazatelya na tu zhe strukturu. Posle poyavleniya takogo opisaniya
sleduyushchee:

    tnode s, *sp;

zadaet s kak ob容kt tipa tnode i sp kak ukazatel' na tnode. S uchetom
etih opisanij s->count oboznachaet chlen count struktury, na kotoruyu
ukazyvaet sp; s.left oboznachaet ukazatel' left na podderevo
struktury s; s.right->tword[0] oboznachaet pervyj simvol chlena
tword poddereva struktury s, na kotoruyu ukazyvaet right.
    Nestaticheskie chleny klassa, predstavlyayushchie dannye i opisannye
podryad i bez ispol'zovaniya specifikacii-dostupa, razmeshchayutsya vnutri
ob容kta tipa klass tak, chto pozzhe opisannye chleny imeyut bol'shie adresa.
Poryadok razmeshcheniya takih chlenov, esli ih opisanie peremezhaetsya
opisaniyami so specifikaciej-dostupa, zavisit ot realizacii ($$R.11.1).
Prinyatye v realizacii pravila vyravnivaniya mogut privesti k tomu,
chto dva sosednih chlena ne budut raspolagat'sya srazu drug za drugom.
K etomu zhe mogut privesti pravila vydeleniya pamyati dlya virtual'nyh
funkcij ($$R.10.2) i virtual'nyh bazovyh klassov ($$R.10.1);
sm. takzhe $$R.5.4.
    Funkciya-chlen ($$R.9.3), imya kotoroj sovpadaet s imenem klassa,
yavlyaetsya konstruktorom ($$R.12.1). Imya staticheskogo chlena dannyh,
elementa perechisleniya, chlena bezymyannogo ob容dineniya ili vlozhennogo
tipa ne mozhet sovpadat' s imenem klassa.



Funkciya, opisannaya kak chlen (bez specifikacii friend $$R.11.4),
nazyvaetsya funkciya-chlen i vyzyvaetsya v sootvetstvii s sintaksisom
chlena klassa ($$R.5.2.4), naprimer:

      struct tnode {
         char tword[20];
         int count;
         tnode *left;
         tnode *right;
         void set(char*, tnode* l, tnode *r);
      };

Zdes' set yavlyaetsya funkciej-chlenom i mozhet vyzyvat'sya tak:

      void f(tnode n1, tnode n2)
      {
         n1.set("abc",&n2,0);
         n2.set("def",0,0);
       }

   Schitaetsya, chto opredelenie funkcii-chlena prinadlezhit oblasti
vidimosti ee klassa. |to oznachaet, chto v funkcii-chlene (esli ona
nestaticheskaya, $$R.9.4) mozhno neposredstvenno ispol'zovat' imena
chlenov ee klassa. V staticheskoj funkcii-chlene mozhno neposredstvenno
ispol'zovat' imena tol'ko staticheskih chlenov, elementov perechisleniya
i vlozhennyh tipov. Esli opredelenie funkcii-chlena nahoditsya vne
opisaniya klassa, ee imya sleduet utochnit' imenem klassa s pomoshch'yu
operacii ::, naprimer:

       void tnode::set(char* w, tnode* l, tnode* r)
       {
         count = strlen(w)+1;
         if (sizeof(tword)<=count)
            error("tnode string too long");
         strcpy(tword,w);
         left = 1;
         right = r;
       }

Oboznachenie tnode::set ukazyvaet, chto funkciya set yavlyaetsya chlenom i
nahoditsya v oblasti vidimosti klassa tnode. Imena chlenov tword,
count, left i right otnosyatsya k chlenam togo ob容kta, s imenem
kotorogo vyzyvalas' Poetomu v vyzove n1.set("abc",&n2,0) tword
oboznachaet n1.tword, a v vyzove n2.set("def",0,0) tword oboznachaet
n2.tword. Funkcii strlen, error i strcpy dolzhny byt' opisany gde-to
v programme.
    CHleny mozhno opredelyat' ($$R.3.1) vne opisaniya klassa; esli v
opisanii klassa oni byli opisany, no ne opredeleny, ih ne sleduet
opisyvat' zanovo, sm. $$R.3.3. Posle opredeleniya klassa
funkcii-chleny etogo klassa mozhno ispol'zovat' pri opisanii druzej.
Vsyakaya vyzyvaemaya v programme funkciya-chlen dolzhna imet' v tochnosti
odno opredelenie.
    Rezul'tat vyzova nestaticheskoj funkcii-chlena ($$R.9.4) klassa X,
kogda ona vyzyvaetsya ne s ob容ktom klassa X, neopredelen.



V nestaticheskoj ($$R.9.3) funkcii-chlene sluzhebnoe slovo this oboznachaet
ukazatel' na ob容kt, s kotorym eta funkciya vyzyvalas'. V funkcii-chlene
klassa X tip this est' X *const, esli tol'ko funkciya-chlen ne opisana
so specifikaciej const ili volatile; dlya etih sluchaev this imeet
tip const X *const ili volatile X *const sootvetstvenno. Esli
funkciya opisana s ukazaniem const i volatile, to tip this budet
const volatile X *const, sm. takzhe $$R.18.3.3. Privedem primer:

     struct s {
        int a;
        int f() const;
        int g() { return a++; }
        int h() const { return a++; }  // oshibka
     };

     int s::f() const { return a; }

Operaciya a++ v tele funkcii s::h oshibochna, poskol'ku s ee pomoshch'yu
delaetsya popytka izmenit' ob容kt (chast' ego), s kotorym vyzyvalas'
funkciya s::h(). |to nedopustimo dlya funkcii-chlena, opisannoj so
specifikaciej const, t.k. this yavlyaetsya ukazatelem na const, inymi
slovami, *this imeet specifikaciyu const.
   Funkciya-chlen const (t.e. funkciya-chlen, opisannaya so specifikaciej
const) mozhet vyzyvat'sya kak dlya ob容ktov const, tak i dlya ob容ktov
bez specifikacii const, togda kak funkciya-chlen bez specifikacii
const mozhet vyzyvat'sya tol'ko dlya ob容ktov bez specifikacii const,
naprimer:

     void k(s& x, const s& y)
     {
       x.f();
       x.g();
       y.f();
       y.g();   // oshibka
     }

Zdes' vyzov y.g() yavlyaetsya oshibkoj, t.k. y est' const, a s::g() -
funkciya-chlen bez specifikacii const, kotoraya mozhet izmenyat'
(i izmenyaet) ob容kty, dlya kotoryh ona vyzyvalas'.
   Analogichno, tol'ko funkciya-chlen volatile (t.e. funkciya-chlen,
opisannaya so specifikaciej volatile) mozhet vyzyvat'sya dlya ob容ktov
so specifikaciej volatile. Funkciya-chlen mozhet byt' odnovremenno
const i volatile.
   Dlya ob容ktov const ili volatile mogut vyzyvat'sya konstruktory
($$R.12.1) i destruktory ($$R.12.4). Konstruktory ($$R.12.1) i
destruktory ($$R.12.4) nel'zya opisyvat' so specifikaciyami const
ili volatile.



Funkciyu-chlen mozhno opredelit' ($$R.8.3) v opisanii klassa, v
takom sluchae ona schitaetsya podstanovkoj (inline, $$R.7.1.2).
Opredelyat' funkciyu v opisanii klassa - eto ekvivalentno tomu,
chtoby opisyvat' funkciyu i opredelyat' ee so specifikaciej inline
srazu zhe posle opisaniya klassa. Schitaetsya, chto takoj perenos
opredeleniya funkcii proishodit posle preprocessornoj obrabotki
do stadii sintaksicheskogo analiza i kontrolya tipov. Poetomu
programmnyj fragment

      int b;
      struct x {
         char* f() { return b; }
         char* b;
      };

ekvivalenten

      int b;
      struct x {
         char* f();
         char* b;
      };

      inline char* x::f() { return b; } // perenos

Zdes' v funkcii x::f() ispol'zuetsya x::b, a ne global'noe b.
   Funkcii-chleny mozhno opredelyat' dazhe v opisanii lokal'nyh ili
vlozhennyh klassov, gde takoj perenos budet sintaksicheski nezakonnym.
Lokal'nye klassy obsuzhdayutsya v R.9.8, a vlozhennye klassy v $$R.9.7.



Dlya chlena klassa, predstavlyayushchego dannye ili funkciyu, mozhno pri opisanii
klassa zadat' specifikaciyu static. Dlya staticheskogo chlena,
predstavlyayushchego dannye, v programme sushchestvuet tol'ko odin ekzemplyar,
kotorym vladeyut vse ob容kty etogo klassa. Staticheskij chlen ne yavlyaetsya
chast'yu ob容kta klassa. Staticheskie chleny global'nogo klassa
podlezhat vneshnemu svyazyvaniyu ($$R.3.3). Opisanie staticheskogo chlena,
predstavlyayushchego dannye, v opisanii klassa ne schitaetsya opredeleniem.
Opredelenie dolzhno byt' dano v drugom meste, sm. takzhe. $$R.18.3.
    Staticheskaya funkciya-chlen ne imeet ukazatel' this, poetomu dlya
dostupa k nestaticheskim chlenam svoego klassa ona dolzhna ispol'zovat'
operacii . ili ->. Staticheskaya funkciya-chlen ne mozhet byt' virtual'noj.
Nedopustimy staticheskie i nestaticheskie funkcii-chleny s odnim imenem
i odinakovymi tipami parametrov.
    Staticheskie chleny lokal'nogo klassa ($$R.9.8) ne podlezhat
svyazyvaniyu i ne mogut opredelyat'sya vne opisaniya klassa. Otsyuda
sleduet, chto lokal'nye klassy ne mogut imet' staticheskih chlenov,
predstavlyayushchih dannye.
    K staticheskomu chlenu mem klassa c1 mozhno obrashchat'sya kak c1::mem
($$R.5.1), t.e. nezavisimo ni ot kakogo ob容kta. K nemu takzhe mozhno
obrashchat'sya s pomoshch'yu operacij dostupa k chlenam . i  ->. Esli k
staticheskomu chlenu proishodit obrashchenie s pomoshch'yu operacij dostupa,
vyrazheniya, stoyashchie sleva ot . ili -> ne ekvivalentny. Staticheskij
chlen mem sushchestvuet dazhe, esli ne sozdano ni odnogo ob容kta klassa
c1. V primere nizhe run_chain, idle i drugie chleny sushchestvuyut dazhe,
esli ne bylo sozdano ni odnogo ob容kta klassa process:

        class process {
          static int no_of_process;
          static process* run_chain;
          static process* running;
          static process* idle;
          // ...
        public:
          // ...
          int state();
          static void reshedule();
          // ...
        };

Zdes' k funkcii reshedule mozhno obratit'sya bez ukazaniya ob容kta
klassa process takim obrazom:

        void f()
        {
          process::reshedule();
        }

  Staticheskie chleny global'nyh klassov inicializiruyutsya tochno tak zhe
kak global'nye ob容kty, no oblast' ih vidimosti - fajl, naprimer:

        void process::reshedule() { /* ... */ };
        int process::no_of_process = 1;
        process* process::running = get_main();
        process* process::run_chain = process::running;

Staticheskie chleny podchinyayutsya obychnym pravilam dostupa k chlenam
klassa ($$R.11), za isklyucheniem togo, chto ih mozhno inicializirovat'
v fajlovoj oblasti vidimosti.
    V tipe staticheskogo chlena ne uchastvuet imya klassa, tak tip
process::no_of_process est' int, a tip &process::reshedule() -
void(*)().




Ob容dinenie mozhno predstavit' kak strukturu, vse chleny imeyut
nulevoe smeshcheniya, a razmer ee dostatochno velik, chtoby
vmeshchat' lyuboj iz ee chlenov. V lyuboj moment vremeni ob容dinenie
mozhet soderzhat' tol'ko odin chlen. V ob容dinenii mogut byt'
funkcii-chleny (v tom chisle konstruktory i destruktory), no ne
virtual'nye funkcii ($$R.10.2). Ob容dinenie ne mozhet imet' bazovyh
klassov i ne mozhet samo ispol'zovat'sya v kachestve bazovogo klassa.
CHlenom ob容dineniya ne mozhet byt' ob容kt klassa s konstruktorom ili
destruktorom, a takzhe s opredelennoj pol'zovatelem operaciej
prisvaivaniya ($$R.13.4.3). Ob容dinenie ne mozhet soderzhat' staticheskih
chlenov, predstavlyayushchih dannye.
    Ob容dinenie vida

        union { spisok-chlenov }

nazyvaetsya bezymyannym ob容dineniem, ono opredelyaet ob容kt bez imeni
(i bez tipa). Imena vseh chlenov bezymyannogo ob容dineniya dolzhny
otlichat'sya ot drugih imen v toj oblasti vidimosti, v kotoroj opisano
ob容dinenie; ih mozhno ispol'zovat' v etoj oblasti vidimosti
neposredstvenno, bez obychnyh operacij dostupa k chlenam ($$R.5.2.4).
Privedem primer:

       void f()
       {
         union { int a; char* p; };
         a = 1;
         // ...
         p = "Jennifer";
         // ...
        }

Zdes' a i p ispol'zuyutsya kak obychnye peremennye (ne chleny), no poskol'ku
oni vhodyat v odno ob容dinenie, ih adresa sovpadayut.
   Global'nye bezymyannye ob容dineniya mozhno opisat' so specifikaciej
static. Bezymyannye ob容dineniya ne dolzhny soderzhat' chastnyh ili
zashchishchennyh chlenov ($$R.11), a takzhe funkcij-chlenov.
   Esli opisany ob容kty ob容dineniya ili ukazateli na nego, to
ono ne schitaetsya bezymyannym, naprimer,

        union { int aa; char* p; } obj, *ptr=&obj;
        aa = 1;      // oshibka
        ptr->aa = 1; // normal'no

Zdes' prisvaivanie prostomu imeni aa nezakonno, t.k. imya chlena ne
privyazano ni k kakomu ob容ktu.
   Inicializaciya ob容dinenij, ne imeyushchih konstruktorov, opisyvaetsya
v $$R.8.4.1.



Konstrukciya opisatel'-chlena, imeyushchaya vid,
     identifikator opt : vyrazhenie-konstanta
zadaet bitovoe pole, dlina kotorogo otdelyaetsya ot ego imeni
dvoetochiem. Razmeshchenie bitovyh polej v ob容kte klassa zavisit ot
realizacii. Polya upakovyvayutsya v nekotorye adresuemye elementy
pamyati. Na odnih mashinah polya mogut vyhodit' za granicy etih
elementov, na drugih - net. Vyravnivanie bitovyh polej tozhe opredelyaetsya
realizaciej. Na odnih mashinah znacheniya pomeshchayutsya v bitovye polya
sprava nalevo, na drugih - sleva napravo.
   CHtoby ustanovit' zadannoe raspolozhenie polej s pomoshch'yu dopolneniya
nulyami, ispol'zuyut bezymyannye bitovye polya. Osobyj sluchaj, kogda
ispol'zuetsya bezymyannoe pole nulevoj dliny. Ono zadaet vyravnivanie
sleduyushchego bitovogo polya po granice elementa pamyati, ispol'zuemogo
pri razmeshchenii polej.
   Bezymyannoe pole ne yavlyaetsya chlenom i ne mozhet inicializirovat'sya.
   Bitovye polya dolzhny imet' celochislennyj tip ($$R.3.6.1). Ih
interpretaciya zavisit ot togo, schitaetsya li znachenie polya s obychnym tipom
int (t.e. bez yavnogo ispol'zovaniya signed ili unsigned) znakovym
ili bezznakovym. Operaciya vzyatiya adresa & ne primenima k bitovym
polyam, tak chto ne mozhet byt' ni ukazatelej na bitovye polya, ni ssylok
na nih.



Klass mozhno opisat' v opisanii drugogo klassa. Takoj klass nazyvayut
vlozhennym. Imya vlozhennogo klassa lokal'no po otnosheniyu k
ob容mlyushchemu klassu. Vlozhennyj klass nahoditsya v oblasti vidimosti
ob容mlyushchego klassa. Esli ne schitat' yavnogo ispol'zovaniya ukazatelej,
ssylok ili imen ob容ktov, to v opisaniyah vlozhennogo klassa dopustimy
tol'ko imena tipov, staticheskih chlenov i elementov perechisleniya
iz ob容mlyushchego klassa.

        int x;
        int y;

        class enclose {
        public:
         int x;
         static int s;

         class inner {

            void f(int i)
            {
              x = i;   // oshibka: prisvaivanie enclose::x
              s = i;   // normal'no: prisvaivanie enclose ::s
              ::x = i; // normal'no: prisvaivanie global'nomu x
              y = i;   // normal'no: prisvaivanie global'nomu y
            }

            void g(enclose* p, int i)
            {
              p->x = i; // normal'no: prisvaivanie enclose ::x
            }

          };
        };
        inner* p = 0;   // oshibka: `inner' vne oblasti vidimosti

Funkcii-chleny vlozhennogo klassa ne imeyut osobyh prav dostupa k chlenam
ob容mlyushchego klassa, oni podchinyayutsya obychnym pravilam dostupa ($$R.11).
Analogichno, funkcii-chleny ob容mlyushchego klassa ne imeyut osobyh prav
dostupa k chlenam vlozhennogo klassa i podchinyayutsya obychnym pravilam
dostupa, naprimer:

         class E {
            int x;
            class I {
               int y;
               void f(E* p, int i)
               {
                 p->x = i;  // oshibka: E::x chastnyj chlen
               }
             };

             int g(I* p)
             {
               return p->y;  // oshibka: I::y chastnyj chlen
             }
           };

Funkcii-chleny i predstavlyayushchie dannye, staticheskie chleny iz vlozhennogo
klassa mozhno opredelit' v global'noj oblasti vidimosti, naprimer:

           class enclose {
              class inner {
                 static int x;
                 void f(int i);
              };
            };

            typedef enclose::inner ei;
            int ei::x = 1;

            void enclose::inner::f(int i) { /* ... */ }

Podobno funkcii-chlenu druzhestvennaya funkciya, opredelennaya v dannom
klasse, nahoditsya v oblasti vidimosti etogo klassa. Ona podchinyaetsya
tem zhe pravilam svyazyvaniya imen, chto i funkcii-chleny (oni ukazany vyshe
i v $$R.10.4), i ne imeet tak zhe kak oni osobyh prav dostupa k
chlenam ob容mlyushchego klassa i k lokal'nym peremennym funkcij etogo
klassa ($$R.11).



Klass mozhno opisat' v opredelenii funkcii, takoj klass nazyvaetsya
lokal'nym. Imya lokal'nogo klassa schitaetsya lokal'nym v ob容mlyushchej
oblasti vidimosti, a oblast'yu vidimosti lokal'nogo klassa yavlyaetsya
ob容mlyushchaya oblast' vidimosti. V opisaniyah lokal'nogo klassa iz
ob容mlyushchej oblasti vidimosti mozhno ispol'zovat' tol'ko imena tipov,
staticheskih peremennyh, vneshnih peremennyh i funkcij, a takzhe
elementy perechisleniya. Privedem primer:

         int x;
         void f()
         {
           static int s;
           int x;
           extern int g();
           struct local {
              int h() { return x; }   // oshibka: `x' avtomaticheskaya
              int j() { return s; }   // normal'no
              int k() { return ::x; } // normal'no
              int l() { return g(); } // normal'no
           }
         }

   Ob容mlyushchaya funkciya ne imeet osobyh prav dostupa k chlenam lokal'nogo
klassa, ona podchinyaetsya obychnym pravilam dostupa ($$R.11).
Funkciyu-chlen lokal'nogo klassa sleduet opredelyat' v opredelenii etogo
klassa. Lokal'nyj klass ne mozhet imet' staticheskih chlenov,
predstavlyayushchih dannye.



Imena tipov podchinyayutsya tochno takim zhe pravilam oblastej vidimosti,
kak i drugie imena. V chastnosti, imena tipov, opredelennye v opisanii
klassa, nel'zya ispol'zovat' vne etogo klassa bez utochneniya, naprimer:

        class X {
        public:
          typedef int I;
          class Y { /* ... */ }
          I a;
        };

        I b;    // oshibka
        Y c;    // oshibka
        X::Y d; // oshibka

Sleduyushchee polozhenie ogranichivaet zavisimost' ot konteksta pravil
opisaniya chlenov klassa, a tak zhe pravila perenosa tela funkcij,
yavlyayushchihsya podstanovkami. Posle ispol'zovaniya v opisanii klassa
imya konstanty, imya-klassa ili imya-typedef ne mozhet pereopredelyat'sya v
opisanii etogo klassa. Imya, ne yavlyayushcheesya imenem-klassa ili imenem-typedef
ne mozhet byt' opredeleno v opisanii klassa kak imya-klassa ili imya-typedef,
esli ono uzhe ispol'zovalos' inache v opisanii etogo klassa.
Rassmotrim primer:

        typedef int c;
        enum { i = 1 };
        class X {
          char v[i];
          int f() { return sizeof(c); }
          char c;          // oshibka: imya typedef
                           // pereopredelyaetsya posle ispol'zovaniya
          enum { i = 2 };  // oshibka: `i' pereopredelyaetsya posle
                           // ispol'zovaniya v zadanii tipa `char[i]'
        };

       typedef char* T;

       struct Y {
         T a;
         typedef long T;  // oshibka: imya T uzhe ispol'zovano
         T b;
       };



V opisanii klassa mozhno ukazat' spisok bazovyh klassov s pomoshch'yu
sleduyushchih konstrukcij:

       spec-bazovyh:
           : spisok-bazovyh

       spisok-bazovyh:
           specifikaciya-bazovyh
           spisok-bazovyh , specifikaciya-bazovyh

       specifikaciya-bazovyh:
           polnoe-imya-klassa
           virtual specifikaciya-dostupa opt polnoe-imya-klassa
           specifikaciya-dostupa virtual opt polnoe-imya-klassa

       specifikaciya-dostupa:
           private
           protected
           public

Konstrukciya imya-klassa v specifikacii-bazovyh dolzhna oboznachat'
ranee opisannyj klass ($$R.9), kotoryj nazyvaetsya bazovym po
otnosheniyu k opredelyaemomu klassu. Govoryat, chto klass yavlyaetsya
proizvodnym ot svoih bazovyh klassov. Naznachenie konstrukcii
specifikaciya-dostupa ob座asnyaetsya v $$R.11. K chlenam bazovogo klassa,
esli tol'ko oni ne pereopredeleny v proizvodnom klasse, mozhno obrashchat'sya
tak, kak budto oni yavlyayutsya chlenami proizvodnogo klassa. Govoryat,
chto proizvodnyj klass nasleduet chleny bazovogo klassa. S pomoshch'yu
operacii razresheniya oblasti vidimosti :: ($$R.5.1) k chlenu bazovogo
klassa mozhno obrashchat'sya yavno. Takoe obrashchenie vozmozhno i v tom sluchae,
kogda imya chlena bazovogo klassa pereopredeleno v proizvodnom klasse.
Proizvodnyj klass sam mozhet vystupat' kak bazovyj pri kontrole
dostupa, sm. $$R.11.2. Ukazatel' na proizvodnyj klass mozhet neyavno
preobrazovyvat'sya v ukazatel' na odnoznachno opredelennyj i dostupnyj
bazovyj klass ($$R.4.6). Ssylka na proizvodnyj klass mozhet neyavno
preobrazovyvat'sya v ssylku na odnoznachno opredelennyj i dostupnyj
bazovyj klass ($$R.4.7).
   Rassmotrim primer:

        class base {
        public:
           int a, b;
        };

       class derived : public base {
       public:
          int b, c;
       };

       void f()
       {
         derived d;
         d.a = 1;
         d.base::b = 2;
         d.b = 3;
         d.c = 4;
        base* bp = &d;  // standartnoe preobrazovanie derived* v base*
       }

Zdes' prisvaivayutsya znacheniya chetyrem chlenam d, a bp nastraivaetsya
na d.
   Klass nazyvaetsya pryamym bazovym, esli on nahoditsya v spiske-bazovyh,
i kosvennym bazovym, esli sam ne yavlyayas' pryamym bazovym, on sluzhit
bazovym dlya odnogo iz klassov spiska-bazovyh.
   Otmetim, chto v oboznachenii imya-klassa :: imya konstrukciya, imya mozhet
byt' imenem chlena kosvennogo bazovogo klassa. Takoe oboznachenie
prosto ukazyvaet klass, v kotorom sleduet nachinat' poisk etogo imeni.
Privedem primer:

       class A { public: void f(); }
       class B : public A { };
       class C : public B { public: void f(); }

       void C::f()
       {
         f();    // vyzov f() iz C
         A::f(); // vyzov f() iz A
         B::f(); // vyzov f() iz A
       }

Zdes' dvazhdy vyzyvaetsya A::f(), poskol'ku eto edinstvennaya funkciya f()
v klasse B.
    Inicializaciya ob容ktov, predstavlyayushchih bazovye klassy, zadaetsya
v konstruktorah, sm. $$R.12.6.2.



Klass mozhet byt' proizvodnym po otnosheniyu k lyubomu chislu bazovyh
klassov. Privedem primer:

       class A { /* ... */ };
       class B { /* ... */ };
       class C { /* ... */ };
       class D : public A, public B, public C { /* ... */ };

Ispol'zovanie bolee, chem odnogo pryamogo bazovogo klassa nazyvaetsya
mnozhestvennym nasledovaniem.
   Poryadok nasledovaniya ne vazhen, esli ne uchityvat' voprosov,
svyazannyh so standartnoj inicializaciej s pomoshch'yu konstruktora
($$R.12.1), unichtozheniem ($$R.12.4) i razmeshcheniem v pamyati
($$r.5.4, $$R.9.2, $$R.11.1). Poryadok vydeleniya pamyati dlya bazovyh
klassov opredelyaetsya realizaciej.
   Nel'zya ukazyvat' klass v kachestve pryamogo bazovogo po otnosheniyu
k proizvodnomu klassu bolee odnogo raza, no kosvennym bazovym klassom
on mozhet byt' neodnokratno.

       class B { /* ... */ };
       class D : public B, public B { /* ... */ }; // nedopustimo

       class L { /* ... */ };
       class A : public L { /* ... */ };
       class B : public L { /* ... */ };
       class C : public A, public B { /* ... */ }; // normal'no

Zdes' ob容kt klassa C budet imet' dva vlozhennyh ob容kta klassa L.
   K specifikacii bazovogo klassa mozhno dobavit' sluzhebnoe slovo
virtual. Otdel'nyj ob容kt virtual'nogo bazovogo klassa V razdelyaetsya
mezhdu vsemi bazovymi klassami, kotorye ukazali V pri zadanii svoih
bazovyh klassov. Privedem primer:

       class V { /* ... */ };
       class A : virtual public V { /* ... */ };
       class B : virtual public V { /* ... */ };
       class C : public A, public B { /* ... */ };

Zdes' ob容kt klassa C budet imet' tol'ko odin vlozhennyj ob容kt
klassa V.
   Klass mozhet soderzhat' virtual'nye i nevirtual'nye bazovye klassy odnogo
tipa, naprimer:

       class B { /* ... */ };
       class X : virtual public B { /* ... */ };
       class Y : virtual public B { /* ... */ };
       class Z : public B { /* ... */ };
       class AA : public X, public Y, public Z { /* ... */ };

Zdes' ob容kt klassa AA budet imet' dva vlozhennyh ob容kta klassa B:
iz klassa Z  i virtual'nyj, razdelyaemyj mezhdu klassami X i Y.



Dostup k bazovomu klassu dolzhen byt' zadan odnoznachno. Dostup k
chlenu bazovogo klassa schitaetsya neodnoznachnym, esli vyrazhenie,
ispol'zuemoe dlya dostupa, zadaet bolee odnoj funkcii, ob容kta,
tipa ili elementa perechisleniya. Proverka na odnoznachnost' proishodit
do proverki vozmozhnosti dostupa ($$R.11). Privedem primer:

       class A {
       public:
         int a;
         int (*b)();
         int f();
         int f(int);
         int g();
       };

       class B {
          int a;
          int b();
       public:
          int f();
          int g();
          int h();
          int h(int);
       };

       class C : public A, public B { };

       void g(C* pc)
       {
         pc->a = 1;    // oshibka: neodnoznachnost': A::a ili B::a
         pc->b();      // oshibka: neodnoznachnost': A::b ili B::b
         pc->f();      // oshibka: neodnoznachnost': A::f ili B::f
         pc->f(1);     // oshibka: neodnoznachnost': A::f ili B::f
         pc->g();      // oshibka: neodnoznachnost': A::g ili B::g
         pc->g = 1;    // oshibka: neodnoznachnost': A::g ili B::g
         pc->h();      // normal'no
         pc->h(1);     // normal'no
       }

Esli imya peregruzhennoj funkcii ustanovleno odnoznachno, to prezhde
proverki vozmozhnosti dostupa proishodit eshche i razreshenie peregruzki.
Neodnoznachnost' mozhno ustranit', utochnyaya ispol'zuemoe imya imenem
klassa, naprimer, tak:

       class A {
       public:
         int f();
       };

       class B {
       public:
         int f();
       };

       class C : public A, public B {
         int f() { return A::f() + B::f(); }
       };

Esli ispol'zuyutsya virtual'nye bazovye klassy, do otdel'noj funkcii,
ob容kta, tipa ili elementa perechisleniya mozhno dobrat'sya neskol'kimi
putyami, dvigayas' po napravlennomu aciklichnomu grafu, kotoryj
obrazuyut bazovye klassy. No eto ne yavlyaetsya neodnoznachnost'yu.
Identichnoe zhe ispol'zovanie nevirtual'nyh bazovyh klassov
porozhdaet neodnoznachnost', poskol'ku v etom sluchae uchastvuet v
zadanii dostupa bolee odnogo vlozhennogo ob容kta. Privedem primer:

       class V { public: int v; };
       class A { public: int a; };
       class B : public A, public virtual V { };
       class C : public A, public virtual V { };

       class D : public B, public C { public: void f(); };

       void D::f()
       {
         v++;   // normal'no
         a++;   // oshibka, neodnoznachnost':  `a' v `D' vhodit dvazhdy
       }

Esli ispol'zuyutsya virtual'nye bazovye klassy, vozmozhno chto
dvigayas' po napravlennomu aciklichnomu grafu, mozhno dobrat'sya bolee,
chem do odnogo imeni funkcii, ob容kta ili elementa perechisleniya. |to,
konechno, neodnoznachnost', no krome sluchaya, kogda odno imya dominiruet
nad drugimi. Identichnoe ispol'zovanie nevirtual'nyh bazovyh klassov
vsegda privodit k neodnoznachnosti, t.k. v etom sluchae vsegda uchastvuet
bolee odnogo vlozhennogo ob容kta.
     Schitaetsya, chto imya B::f dominiruet nad imenem A::f, esli klass
A yavlyaetsya dlya klassa B bazovym. Esli odno imya dominiruet nad
drugim, oni ne mogut privesti k neodnoznachnosti: v situacii vybora
ispol'zuetsya vsegda dominiruyushchee imya. Privedem primer:

       class V { public: int f(); int x; };
       class B : public virtual V { public: int f(); int x; };
       class C : public virtual V { };

       class D : public B, public C { void g(); };

       void D::g()
       {
         x++;   // normal'no: B::x dominiruet nad V::x
         f();   // normal'no: B::f() dominiruet nad V::f()
       }

V rezul'tate yavnogo ili neyavnogo preobrazovaniya ukazatelya ili ssylki
na proizvodnyj klass v ukazatel' ili ssylku na odin iz ego bazovyh
klassov, eti ukazatel' ili ssylka dolzhny ukazyvat' tol'ko na tot
zhe samyj ob容kt, kotoryj predstavlyaet bazovyj klass. Privedem primer:

       class V { };
       class A { };
       class B : public A, public virtual V { };
       class C : public A, public virtual V { };
       class D : public B, public C { };

       void g()
       {
         D d;
         B* pb = &d;
         A* pa = &d;  // oshibka, neodnoznachnost': A iz C ili A iz B?
         v* pv = &d;  // normal'no: tol'ko odin vlozhennyj ob容kt V
       }




Esli klass base soderzhit virtual'nuyu ($$R.7.1.2) funkciyu vf, a
proizvodnyj ot nego klass derived takzhe soderzhit funkciyu vf togo
zhe tipa, togda vyzov vf dlya ob容kta klassa derived yavlyaetsya
obrashcheniem k derived::vf, dazhe esli dostup k etoj funkcii proishodit
cherez ukazatel' ili ssylku na klass base. Govoryat, chto funkciya
proizvodnogo klassa podavlyaet funkciyu bazovogo klassa. Odnako, esli
tipy funkcij ($$R.8.2.5) razlichny, funkcii schitayutsya raznymi i mehanizm
virtual'nosti ne dejstvuet (sm. takzhe $$R.13.1). Schitaetsya oshibkoj,
esli funkciya proizvodnogo klassa otlichaetsya ot virtual'noj funkcii
bazovogo klassa tol'ko tipom vozvrashchaemogo znacheniya. Rassmotrim
primer:

        struct base {
          virtual void vf1();
          virtual void vf2();
          virtual void vf3();
          void f();
        };

        class derived : public base {
        public:
          void vf1();
          void vf2(int);     // skryvaet base::vf2()
          char vf3();        // oshibka: razlichie tol'ko v tipe
                             // vozvrashchaemogo znacheniya
        }

        void g()
        {
          derived d;
          base* bp = &d;     // standartnoe preobrazovanie: derived* v base*
          bp->vf1();         // vyzov derived::vf1
          bp->vf2();         // vyzov base::vf2
          bp->f();           // vyzov base::f
        }

Zdes' tri vyzova dlya ob容kta d klassa derived privedut k obrashcheniyam k
derived::vf1, base::vf2 i base::f sootvetstvenno. Inymi slovami,
interpretaciya vyzova virtual'noj funkcii zavisit ot tipa ob容kta,
dlya kotorogo ona vyzyvaetsya, togda kak interpretaciya vyzova
nevirtual'noj funkcii-chlena zavisit tol'ko ot tipa ukazatelya ili
ssylki na etot ob容kt. Naprimer, vyrazhenie bp->vf1()
privedet k vyzovu derived::vf1(), poskol'ku bp ukazyvaet na ob容kt
klassa derived, v kotorom funkciya derived::vf1() podavlyaet
virtual'nuyu funkciyu base::vf1().
   Nalichie specifikacii virtual oznachaet, chto funkciya yavlyaetsya chlenom,
poetomu virtual'naya funkciya ne mozhet byt' global'noj funkciej (ne chlenom)
($$R.7.1.2). Tochno tak zhe virtual'naya funkciya ne mozhet byt'
staticheskim chlenom, t.k. dlya vyzova virtual'noj funkcii neobhodimo
nalichie opredelennogo ob容kta, kotoryj ukazyvaet, kakuyu funkciyu
nado vyzyvat'. V drugom klasse virtual'nuyu funkciyu mozhno opisat' kak
druga. Funkciya, podavlyayushchaya virtual'nuyu, sama schitaetsya virtual'noj
funkciej. Specifikaciyu virtual mozhno ispol'zovat' dlya podavlyayushchej
funkcii proizvodnogo klassa, no eto izbytochno. Virtual'naya funkciya
mozhet byt' opredelena ili opisana v bazovom klasse kak chistaya
($$R.10.3). Virtual'nuyu funkciyu, kotoraya opredelena v bazovom klasse,
ne nuzhno opredelyat' v proizvodnom klasse: pri vseh vyzovah budet
ispol'zovat'sya funkciya, opredelennaya v bazovom klasse.
    Mehanizm virtual'nosti pri vyzove otklyuchaetsya, esli est' yavnoe
utochnenie imeni s pomoshch'yu operatora razresheniya oblasti vidimosti
 ($$R.5.1), naprimer:

       class B { public: virtual void f(); };
       class D : public B { public: void f(); };

       void D::f() { /* ... */ B::f(); }

Zdes' obrashchenie k f iz D privodit k vyzovu B::f, a ne D::f.



Abstraktnye klassy dayut sredstvo dlya predstavleniya v yazyke obshchih
ponyatij, takih, naprimer, kak figura, dlya kotoryh mogut ispol'zovat'sya
tol'ko konkretnye ih varianty, naprimer, krug ili kvadrat. Krome togo
abstraktnyj klass pozvolyaet zadat' interfejs, raznoobraznye realizacii
kotorogo predstavlyayut proizvodnye klassy.
   Abstraktnym nazyvaetsya klass, kotoryj mozhno ispol'zovat' tol'ko
kak bazovyj dlya nekotorogo drugogo klassa, t.e. nel'zya sozdat'
nikakogo ob容kta abstraktnogo klassa krome togo, kotoryj predstavlyaet
bazovyj klass dlya nekotorogo proizvodnogo klassa. Klass schitaetsya
abstraktnym, esli v nem est' hotya by odna chistaya virtual'naya
funkciya. Pri opisanii klassa virtual'naya funkciya opisyvaetsya kak
chistaya s pomoshch'yu specifikacii-chistoj ($$R.9.2). CHistuyu virtual'nuyu
funkciyu ne nuzhno opredelyat', esli tol'ko ona yavno ne vyzyvaetsya
s pomoshch'yu konstrukcii utochnennoe-imya ($$R.5.1). Rassmotrim primer:

         class point { /* ... */ };
         class shape {     // abstraktnyj klass
           point center;
           // ...
         public:
           point where() { return center; }
           void move(point p) { center=p; draw(); }
           virtual void rotate(int) = 0; // chistaya virtual'naya
           virtual void draw() = 0;      // chistaya virtual'naya
           // ...
         };

Abstraktnyj klass nel'zya ispol'zovat' kak tip formal'nogo parametra,
tip vozvrashchaemogo znacheniya, a takzhe kak tip v operacii yavnogo
preobrazovaniya tipa. Mozhno opisyvat' ukazateli i ssylki na abstraktnyj
klass, naprimer:

         shape    x;       // oshibka: ob容kt abstraktnogo klassa
         shape*   p;       // normal'no
         shape    f();     // oshibka
         void g(shape);    // oshibka
         shape& h(shape&); // normal'no

  CHistye virtual'nye funkcii i nasleduyutsya kak chistye virtual'nye
funkcii, naprimer:

         class ab_circle : public shape {
           int radius;
         public:
           void rotate(int) { }
           // ab_circle::draw() chistaya virtual'naya funkciya
         };

Poskol'ku funkciya shape::draw() yavlyaetsya chistoj virtual'noj funkciej,
to takoj zhe budet po opredeleniyu i funkciya ab_circle::draw(). Dlya
privedennogo nizhe opisaniya klass circle ne budet abstraktnym, i u
funkcii circle::draw() gde-to dolzhno sushchestvovat' opredelenie.

         class circle : public shape {
            int radius:
         public:
            void rotate(int) { }
            void draw();  // dolzhna byt' gde-to opredelena
         };

   Funkcii-chleny mozhno vyzyvat' iz konstruktora abstraktnogo klassa,
rezul'tat pryamogo ili kosvennogo vyzova chistoj virtual'noj funkcii
dlya ob容kta, sozdannogo s pomoshch'yu takogo konstruktora, neopredelen.



Teper' mozhno svesti voedino pravila oblastej vidimosti dlya programmy
na S++. |ti pravila odinakovo primenimy dlya vseh imen (vklyuchaya
imya-typedef ($$R.7.1.3) i imya-klassa ($$R.9.1)) i v lyubom
kontekste, dlya kotorogo oni dopustimy po sintaksisu yazyka. Zdes'
rassmatrivayutsya tol'ko oblasti vidimosti na leksicheskom urovne,
voprosy svyazyvaniya obsuzhdayutsya v $$R.3.3. Ponyatie momenta opisaniya
bylo vvedeno v $$R.3.2.
    Vsyakoe ispol'zovanie imeni dolzhno byt' odnoznachnym (ne schitaya
peregruzki) v oblasti ego vidimosti ($$R.10.1.1). Pravila dostupa
($$R.11) nachinayut dejstvovat' tol'ko togda, kogda imya mozhno odnoznachno
najti v oblasti ego vidimosti. Tol'ko pri uslovii, chto prava dostupa
k imeni ne narusheny, nachinaetsya proverka tipa ob容kta, funkcii ili
elementa perechisleniya.
   Imya, kotoroe ispol'zuetsya vne lyuboj funkcii ili klassa, ili pered
kotorym stoit unarnaya operaciya razresheniya oblasti vidimosti ::
(i kotoroe ne utochnyaetsya binarnoj operaciej :: ili operaciyami ->
ili .), dolzhno byt' imenem global'nogo ob容kta, ili funkcii, ili
elementa perechisleniya, ili tipa.
   Imya, zadavaemoe posle X:: ili obj., gde obj tipa X ili tipa
ssylka na X, a takzhe imya, zadavaemoe posle ptr->, gde ptr tipa ukazatel'
na X, dolzhno byt' imenem chlena klassa X ili chlenom bazovogo po
otnosheniyu k X klassa. Pomimo etogo, v obrashchenii ptr->imya  ptr mozhet
byt' ob容ktom klassa Y, v kotorom est' funkciya operator->(),
opisannaya takim obrazom, chto ptr->operator() v konechnom schete
okazyvaetsya ukazatelem na X ($$R.13.4.6).
  Imya, kotoroe ne utochnyaetsya odnim iz opisannyh vyshe sposobov, i,
kotoroe ispol'zuetsya v funkcii, ne yavlyayushchejsya chlenom klassa,
dolzhno byt' opisano v tom bloke, gde ono ispol'zuetsya, ili v
ob容mlyushchem bloke ili dolzhno byt' global'nym. Opisanie lokal'nogo imeni
skryvaet opisaniya togo zhe imeni v ob容mlyushchih blokah, a takzhe ego
opisaniya kak global'nogo imeni. V chastnosti, peregruzka imeni
nevozmozhna dlya imen v raznyh oblastyah vidimosti ($$R.13.4).
  Imya, kotoroe ne utochnyaetsya odnim iz opisannyh vyshe sposobov, i,
kotoroe ispol'zuetsya v funkcii, yavlyayushchejsya nestaticheskim chlenom
klassa X, dolzhno byt' opisano ili v tom bloke, gde ono ispol'zuetsya,
ili v ob容mlyushchem bloke, i ono dolzhno byt' chlenom klassa X, ili
chlenom bazovogo po otnosheniyu k X klassa, ili eto imya dolzhno byt'
global'nym. Opisanie lokal'nyh imen skryvaet opisanie etih zhe imen
v ob容mlyushchih blokah, v chlenah klassa etoj funkcii i sredi global'nyh
imen. Opisanie chlena skryvaet analogichnye opisanie s tem zhe imenem
v bazovyh klassah i sredi global'nyh imen.
   Imya, kotoroe ne utochnyaetsya odnim iz opisannyh vyshe sposobov, i,
kotoroe ispol'zuetsya v staticheskoj funkcii-chlene klassa X, dolzhno
byt' opisano ili v tom bloke, gde ono ispol'zuetsya, ili v ob容mlyushchem
bloke, i dolzhno byt' staticheskim chlenom klassa X, ili bazovogo po
otnosheniyu k X klassa, ili ono dolzhno byt' global'nym imenem.
   Imya formal'nogo parametra funkcii, zadannoe pri ee opredelenii
($$R.8.3), prinadlezhit oblasti vidimosti, sovpadayushchej s naibol'shim
blokom funkcii (v chastnosti, yavlyaetsya lokal'nym imenem). Imya
formal'nogo parametra funkcii, zadannoe v ee opisanii ($$R.8.2.5),
a ne opredelenii, prinadlezhit lokal'noj oblasti vidimosti, kotoraya
ischezaet srazu zhe posle opisaniya funkcii. Standartnye znacheniya
parametrov nahodyatsya v oblasti vidimosti, opredelyaemoj v moment
opisaniya ($$R.3.2) formal'nyh parametrov funkcii; v nih ne dolzhny
ispol'zovat'sya lokal'nye peremennye ili nestaticheskie chleny klassa,
i oni vychislyayutsya pri kazhdom vyzove funkcii ($$R.8.2.6).
   Inicializator-ctor ($$R.12.6.2) vychislyaetsya v oblasti vidimosti
naibol'shego bloka konstruktora, dlya kotorogo on zadan. V chastnosti,
v nem mozhno ispol'zovat' imena formal'nyh parametrov.



CHlen klassa mozhet byt':
    chastnym (private); eto znachit, chto ego imya mozhno ispol'zovat'
    tol'ko v funkciyah-chlenah i druz'yah klassa, v kotorom on opisan;

    zashchishchennym (protected); eto znachit, chto ego imya mozhno ispol'zovat'
    tol'ko v funkciyah-chlenah i druz'yah klassa, v kotorom on opisan,
    a takzhe v funkciyah-chlenah i druz'yah klassov, yavlyayushchihsya
    proizvodnymi po otnosheniyu k etomu klassu (sm. $$R.11.5);

    obshchim (public); eto znachit, chto ego imya mozhno ispol'zovat'
    v lyuboj funkcii.
   CHleny klassa, opisannogo so sluzhebnym slovom class, yavlyayutsya
chastnymi po opredeleniyu. CHleny klassa, opisannogo so sluzhebnym
slovom struct ili union, yavlyayutsya obshchimi po opredeleniyu, naprimer:

      class X {
         int ;    // X:: chastnyj po opredeleniyu
      };

      struct S {
         int a;   // S::a obshchij po opredeleniyu
      };



Opisaniya chlenov mogut byt' snabzheny specifikaciej dostupa ($$R.10):
      specifikaciya-dostupa : spisok-chlenov opt
Specifikaciya-dostupa zadaet pravila dostupa k chlenam, kotorye
dejstvuyut do konca zhizni klassa ili poka ne poyavitsya drugaya
specifikaciya-dostupa, naprimer,

      class X {
        int a;  // X::a chastnyj po opredeleniyu: uchityvaetsya 'class'
      public:
        int b;  // X::b obshchij
        int c;  // X::c obshchij
      };

Dopustimo lyuboe chislo specifikacij dostupa i zadavat' ih mozhno v
lyubom poryadke, naprimer,

     struct S {
        int a;  // S::a obshchij po opredeleniyu: uchityvaetsya `struct'
     protected:
        int b;  // S::b zashchishchennyj
     private:
        int c;  // S::c chastnyj
     public:
        int d;  // S:: d obshchij
     };

  Poryadok razmeshcheniya chlenov, predstavlyayushchih dannye, kotorye imeyut
raznye specifikacii-dostupa, opredelyaetsya realizaciej ($$R.9.2).



Esli klass opisan kak bazovyj ($$r.10) po otnosheniyu k
drugomu klassu s pomoshch'yu specifikacii dostupa public, to chleny so
specifikaciej public ili protected iz bazovogo klassa yavlyayutsya
sootvetstvenno chlenami s toj zhe specifikaciej dlya proizvodnogo klassa.
Esli klass opisan kak bazovyj po otnosheniyu k drugomu s pomoshch'yu
specifikacii dostupa private, to chleny so specifikaciej public ili
protected iz bazovogo klassa yavlyayutsya chlenami so specifikaciej
private dlya proizvodnogo klassa. CHastnye chleny bazovogo klassa
ostayutsya nedostupnymi dazhe dlya proizvodnyh klassov, esli tol'ko dlya
obespecheniya dostupa pri opisanii bazovogo klassa ne bylo ispol'zovano
opisanie friend.
    Esli dlya bazovogo klassa ne ukazana specifikaciya-dostupa, to
dlya proizvodnogo klassa, esli on opisan kak struct, predpolagaetsya
specifikaciya public, a esli on opisan so sluzhebnym slovom
class, to - specifikaciya private, naprimer:

       class B { /* ... */ };
       class D1 : private B { /* ... */ };
       class D2 : public B { /* ... */ };
       class D3 : B { /* ... */ }; // `B' chastnyj po opredeleniyu
       struct D4 : public B { /* ... */ };
       struct D5 : private B { /* ... */ };
       struct D6 : B { /* ... */ }; // `B' chastnyj po opredeleniyu

Zdes' klass yavlyaetsya obshchim (public) bazovym klassom dlya D2, D4 i D6
i chastnym (private) bazovym klassom dlya D1, D2 i D5.
    Opisanie bazovogo klassa kak private ne vliyaet na dostup k
staticheskim chlenam bazovogo klassa. Odnako, esli pri obrashchenii k
staticheskomu chlenu ispol'zuetsya ob容kt ili ukazatel', kotoryj
nuzhno preobrazovyvat', to dejstvuyut obychnye pravila preobrazovaniya
ukazatelej.
    V funkciyah-chlenah ili druz'yah klassa X mozhno X* neyavno
preobrazovyvat' v ukazatel' na chastnyj klass, yavlyayushchijsya
neposredstvenno bazovym po otnosheniyu k X.




Ispol'zuya utochnennoe imya, mozhno ustanovit' dostup k chlenu bazovogo
klassa v chasti public ili protected opisaniya proizvodnogo klassa.
|to nazyvaetsya opisaniem dostupa.
   Privedem primer:

       class B {
         int a;
       public:
         int b, c;
         int bf();
       };

       class D : private B {
         int d;
       public:
         B::c;   // adjust access to `B::c'
         int e;
         int df();
       };

       int ef(D&);

Vo vneshnej funkcii ef mozhno ispol'zovat' tol'ko imena c, e, i df.
Poskol'ku funkciya df chlen klassa D, v nej mozhno ispol'zovat'
imena b, c, bf, d, e i df, no ne a. Funkciya bf - chlen klassa B i
v nej mozhno ispol'zovat' chleny a, b, c i bf.
   Opisaniya dostupa ne sleduet ispol'zovat' dlya ogranicheniya dostupa
k chlenu, dostupnomu v bazovom klasse, takzhe kak ne sleduet
ispol'zovat' ego dlya obespecheniya dostupa k chlenu, kotoryj nedostupen
v bazovom klasse, naprimer:

       class B {
       public:
         int a;
       private:
         int b;
       protected:
         int c;
       };

       class D : private B {
       public:
         B::a;    // opisat' `a' kak obshchij chlen D
         B::b;    // oshibka: popytka rasshirit' dostup,
                  // `b' ne mozhet byt' obshchim chlenom D
       protected:
         B::c;    // opisat' `c' kak zashchishchennyj chlen D
         B::a;    // oshibka: popytka suzit' dostup,
                  // `a' ne mozhet byt' zashchishchennym chlenom D
       };

Opisanie dostupa dlya imeni peregruzhennoj funkcii ustanavlivaet
dostup v bazovom klasse ko vsem funkciyam s etim imenem, naprimer:

       class X {
       public:
         f();
         f(int);
       };

       class Y : private X {
       public:
         X::f;   // makes X::f() and X::f(int) public in Y
       };

   Nel'zya v proizvodnom klasse ustanovit' dostup k chlenu bazovogo
klassa, esli v proizvodnom klasse opredelen chlen s etim zhe imenem,
naprimer:

       class X {
       public:
         void f();
       };

       class Y : private X {
       public:
         void f(int);
         X::f;   // oshibka: dva opisaniya f
       };



Drugom klassa nazyvaetsya funkciya, kotoraya ne yavlyaetsya chlenom klassa,
no v kotoroj mozhno ispol'zovat' chastnye i zashchishchennye chleny etogo
klassa. Imya druga ne prinadlezhit oblasti vidimosti klassa, i
druzhestvennaya funkciya ne vyzyvaetsya s pomoshch'yu operacij dostupa k
chlenam ($$R.5.2.4), esli tol'ko ona ne yavlyaetsya chlenom drugogo
klassa. Sleduyushchij primer pokazyvaet razlichie mezhdu chlenami i
druz'yami:

       class X {
         int a;
         friend void friend_set(X*, int);
       public:
         void member_set(int);
       };

       void friend_set(X* p, int i) { p->a = i; }
       void X::member_set(int i) { a = i; }

       void f()
       {
         X obj;
         friend_set(&obj,10);
         obj.member_set(10);
       }

   Esli v opisanii friend ispol'zovano imya peregruzhennoj funkcii
ili operacii, tol'ko funkciya, odnoznachno opredelyaemaya tipami
formal'nyh parametrov, stanovitsya drugom. Funkciya-chlen klassa X
mozhet byt' drugom klassa Y, naprimer:

       class Y {
         friend char* X::foo(int);
         // ...
       };

Mozhno ob座avit' vse funkcii klassa X druz'yami klassa Y s pomoshch'yu
specifikacii-slozhnogo-tipa ($$R.9.1):

       class Y {
         friend class X;
         // ...
       };

Opisanie odnogo klassa kak drug drugogo klassa dopolnitel'no
podrazumevaet, chto chastnye i zashchishchennye chleny klassa, predlagayushchego
druzhbu, mogut ispol'zovat'sya v klasse, poluchayushchem ee, naprimer:

       class X {
         enum { a=100 };
         friend class Y;
       };

       class Y {
         int v[X::a];   // Y drug klassa X
       };

       class Z {
         int v[X::a];   // oshibka: X::a nedostupno
       };

  Esli klass ili funkciya, ob座avlennye kak druz'ya, ne byli opisany,
ih imena popadayut v tu zhe oblast' vidimosti, chto i imya klassa,
soderzhashchego opisanie friend ($$R.9.1).
  Funkciya, poyavivshayasya pervyj raz v opisanii friend, schitaetsya
ekvivalentnoj funkcii, opisannoj kak extern ($$R.3.3, $$r.7.1.1).
  Esli funkciya-drug opredelena v opisanii klassa, ona schitaetsya
funkciej so specifikaciej inline i k nej primenimo pravilo
perenosa opredeleniya funkcii dlya funkcij-chlenov ($$R.9.3.2).
Funkciya-drug, opredelennaya v opisanii klassa, otnositsya na
leksicheskom urovne k oblasti vidimosti etogo klassa. Dlya
funkcii-druga, opredelennoj vne klassa, eto ne tak.
  Na opisanie friend ne vliyaet ukazanie specifikacij-dostupa
($$R.9.2).
Ponyatie druzhby ne yavlyaetsya ni nasleduemym, ni tranzitivnym.
Podtverdim eto primerom:

     class A {
       friend class B;
       int a;
     };

     class B {
       friend class C;
     };

     class C {
       void f(A* p);
       {
         p->a++;   // oshibka: C ne drug klassa A, hotya
                   // yavlyaetsya drugom druga klassa A
       }
     };

     class D : public B {
       void f(A* p)
       {
         p->a++;   // oshibka: D ne drug klassa A, hotya
                   // yavlyaetsya proizvodnym druga klassa A
       }
     };



Drug ili funkciya-chlen proizvodnogo klassa imeet dostup k zashchishchennomu
staticheskomu chlenu bazovogo klassa. Drug ili funkciya-chlen proizvodnogo
klassa mogut poluchit' dostup k zashchishchennomu nestaticheskomu chlenu
odnogo iz svoih bazovyh klassov tol'ko cherez ukazatel', ssylku ili
ob容kt proizvodnogo klassa (ili lyubogo klassa, yavlyayushchegosya
proizvodnym po otnosheniyu k nemu). Rassmotrim primer:

     class B {
     protected:
       int i;
     };

    class D1 : public B {
    };

    class D2 : public B {
      friend void fr(B*, D1*, D2*);
      void mem(B*, D1*);
    };

   void fr(B* pb, D1* p1, D2* p2)
   {
     pb->i = 1;  // nedopustimo
     p1->i = 2;  // nedopustimo
     p2->i = 3;  // normal'no (obrashchenie cherez D2)
   }

   void D2::mem(B* pb, D1* p1)
   {
     pb->i = 1;  // nedopustimo
     p1->i = 2;  // nedopustimo
     i = 3;      // normal'no (obrashchenie cherez this)
   }

   void g(B* pb, D1* p1, D2* p2)
   {
     pb->i = 1;  // nedopustimo
     p1->i = 2;  // nedopustimo
     p2->i = 3;  // nedopustimo
   }



Pravila dostupa ($$r.11) k virtual'noj funkcii opredelyayutsya ee
opisaniem i na nih ne vliyayut pravila dostupa k k funkcii, kotoraya
pozdnee budet podavlyat' ee. Privedem primer:

    class B {
    public:
      virtual f();
    };

    class D : public B {
    private:
      f();
    };

    void f()
    {
      D d;
      B* pb = &d;
      D* pd = &d;

      pb->f();   // normal'no: B::f() obshchij chlen
                 // vyzyvaetsya D::f()
      pd->f();   // oshibka: D::f() chastnyj chlen
    }

Prava dostupa proveryayutsya pri samom vyzove, ispol'zuya tip vyrazheniya,
oboznachayushchee ob容kt, dlya kotorogo vyzyvaetsya funkciya-chlen (v primere
vyshe eto B*). Dostup k funkcii-chlenu v klasse, gde ona opredelena
(D v primere vyshe), v obshchem sluchae neizvesten.



Esli dobrat'sya do imeni mozhno neskol'kimi putyami po grafu, zadayushchemu
mnozhestvennoe nasledovanie, to pravo dostupa etogo imeni schitaetsya
maksimal'nym iz prav, poluchaemyh na raznyh putyah. Poyasnim eto
primerom:

     class W { public: void f(); };
     class A : private virtual W { };
     class B : public virtual W { };
     class C : public A, public B {
        void f() { W::f(); } // normal'no
     };

Poskol'ku W::f() dostupno v C::f() po puti, svyazannomu s obshchim
nasledovaniem iz B, obrashchenie yavlyaetsya zakonnym.



Nekotorye funkcii-chleny schitayutsya special'nymi, poskol'ku oni
vliyayut na to, kak ob容kty klassa sozdayutsya, kopiruyutsya i unichtozhayutsya,
i kak znacheniya odnogo tipa preobrazuyutsya v znacheniya drugogo tipa.
CHasto takie funkcii vyzyvayutsya neyavno.
    |ti funkcii-chleny podchinyayutsya obychnym pravilam dostupa ($$R.11).
Naprimer, opisanie konstruktora so specifikaciej protected
garantiruet, chto sozdavat' ob容kty s ego pomoshch'yu smogut tol'ko
proizvodnye klassy i druz'ya.



Konstruktorom nazyvaetsya funkciya-chlen, imya kotoroj sovpadaet s imenem
klassa, on ispol'zuetsya dlya postroeniya znachenij, imeyushchih tip dannogo
klassa. Esli v klasse est' konstruktor, to kazhdyj ob容kt etogo klassa
pered proizvol'nym ispol'zovaniem budet inicializirovat'sya, sm.
$$R.12.6.
   Konstruktor mozhet vyzyvat'sya dlya ob容kta so specifikaciej const
ili volatile. Sam konstruktor nel'zya opisyvat' so specifikaciej
const ili volatile ($$R.9.3.1). Konstruktor takzhe ne mozhet imet'
specifikaciyu virtual ili static.
   Konstruktory ne nasleduyutsya, odnako, standartnye konstruktory
i konstruktory kopirovaniya pri neobhodimosti sozdayutsya translyatorom
($$R.12.8). Takie konstruktory yavlyayutsya obshchimi.
   Standartnym konstruktorom dlya klassa X yavlyaetsya takoj konstruktor
klassa X, kotoryj mozhno vyzyvat' bez parametrov. Standartnyj
konstruktor dlya klassa X budet sozdan tol'ko togda, kogda dlya klassa
X ne opisano ni odnogo konstruktora.
   Konstruktorom kopirovaniya dlya klassa X nazyvaetsya konstruktor,
kotoryj vyzyvaetsya dlya kopirovaniya ob容kta klassa X, t.e. vyzyvaetsya
s odnim parametrom tipa X. Naprimer, X::X(const X&) i
X::X(X&, int=0) yavlyayutsya konstruktorami kopirovaniya. Konstruktor
kopirovaniya sozdaetsya tol'ko togda, kogda ne opisano ni odnogo
konstruktora kopirovaniya.
   Konstruktor kopirovaniya dlya klassa X ne dolzhen imet' v kachestve
parametra ob容kt tipa X, naprimer X::X(X) nezakonnoe obrashchenie.
   Konstruktor dlya massiva elementov vyzyvaetsya v poryadke
vozrastaniya adresov elementov ($$R.8.2.4).
   Esli u klassa est' bazovye klassy s konstruktorom ili chleny,
yavlyayushchiesya ob容ktami s konstruktorom, ih konstruktory vyzyvayutsya
prezhde, chem konstruktor proizvodnogo klassa. V $$R.12.6.2 ob座asnyaetsya
kak zadayutsya parametry dlya takih konstruktorov i kak opredelyaetsya
poryadok ih vyzova.
   Ob容kt klassa s konstruktorom ne mozhet byt' chlenom ob容dineniya.
   Dlya konstruktora ne nuzhno ukazyvat' nikakogo tipa vozvrashchaemogo
znacheniya, dazhe void. V operatore return v tele konstruktora nel'zya
ukazyvat' vozvrashchaemoe znachenie. Ne dopustima operaciya vzyatiya
adresa konstruktora.
   Konstruktor mozhno yavno ispol'zovat' dlya sozdaniya ob容ktov ego
tipa s pomoshch'yu sleduyushchej zapisi:
        imya-klassa ( spisok-vyrazhenij opt )
Privedem primer:

        complex zz = complex(1,2.3);
        print( complex(7.8,1.2) );

Ob容kt, sozdannyj takim obrazom yavlyaetsya bezymyannym (esli tol'ko
konstruktor ne ispol'zovalsya dlya inicializacii poimenovannoj peremennoj
kak zz vyshe), a vremya ego zhizni ogranicheno vyrazheniem, v kotorom
on byl sozdan, sm. $$R.12.2.
    V konstruktore mozhno vyzyvat' funkciyu-chlen, sm. $$R.12.7.



V nekotoryh situaciyah translyatoru byvaet neobhodimo ili udobno
sozdavat' vremennye ob容kty. Ispol'zovanie vremennyh ob容ktov
zavisit ot realizacii. Esli translyatoru ponadobilsya vremennyj
ob容kt tipa klassa s konstruktorom, on dolzhen obespechit' vyzov
konstruktora dlya etogo vremennogo ob容kta. Analogichno, neobhodimo
vyzyvat' destruktor dlya ob容kta klassa, v kotorom opisan
destruktor. Privedem primer:

        class X {
          // ...
        public:
          // ...
          X(int);
          X(X&);
          ~X();
        };

        X f(X);

        void g()
        {
          X a(1);
          X b = f(X(2));
          a = f(b);
        }

Zdes' nuzhen vremennyj ob容kt dlya postroeniya X(2), prezhde chem
peredat' ego funkcii f() s pomoshch'yu X(X&). Al'ternativnoe reshenie, -
postroit' ob容kt X(2) v pamyati, ispol'zuemoj dlya hraneniya parametra
pri pervom vyzove f(). Pomimo etogo, vremennyj ob容kt mozhet
ponadobit'sya dlya hraneniya rezul'tata f(X(2)) prezhde, chem kopirovat'
ego v ob容kt b s pomoshch'yu X(X&), i zdes' vozmozhno al'ternativnoe
reshenie: hranit' rezul'tat f(X(2)) v pamyati dlya ob容kta b.  S drugoj
storony, sushchestvuet mnogo funkcij f(), dlya kotoryh vypolnenie
vyrazheniya a=f(a) trebuet vremennogo ob容kta ili dlya parametra a,
ili dlya rezul'tata f(a), chtoby izbezhat' nezhelatel'nogo ispol'zovaniya
pamyati, kotoroj pripisyvaetsya imya a.
    Translyator obyazan garantirovat' unichtozhenie vremennyh ob容ktov.
Tochnyj moment unichtozheniya opredelyaetsya realizaciej. S vremennymi
ob容ktami mozhno proizvodit' tol'ko dve operacii: vybrat' znachenie
ob容kta (neyavno kopiruya ego) dlya ispol'zovaniya v drugom vyrazhenii,
ili vzyat' ssylku na nego. Esli znachenie vremennogo ob容kta polucheno,
on schitaetsya nenuzhnym i mozhet unichtozhat'sya nemedlenno. Esli na nego
poluchena ssylka, to unichtozhat' ego nel'zya, poka sushchestvuet ssylka.
Unichtozhenie dolzhno proizojti do vyhoda iz oblasti opredelennosti,
v kotoroj byl sozdan vremennyj ob容kt.
    Drugoj vid vremennyh ob容ktov obsuzhdaetsya v $$R.8.4.3.



Preobrazovaniya ob容ktov klassa mozhno zadat' s pomoshch'yu konstruktorov
ili funkcij preobrazovaniya.
   Takie preobrazovaniya, obychno nazyvaemye pol'zovatel'skimi,
ispol'zuyutsya neyavno v sovokupnosti so standartnymi preobrazovaniyami
($$R.4). Naprimer, funkciyu s formal'nym parametrom tipa X mozhno
vyzyvat' ne tol'ko s parametrom tipa X, no i parametrom tipa T,
esli sushchestvuet preobrazovanie tipa T v X. Pol'zovatel'skie
preobrazovaniya primenyayutsya v teh zhe situaciyah, chto i standartnye:
preobrazovanie inicializatorov ($$R.8.4), parametrov funkcii
($$R.5.2.2), vozvrashchaemyh funkciej znachenij ($$R.6.6.3, $$R.8.2.5),
vyrazhenij fakticheskih parametrov ($$R.5), vyrazhenij, upravlyayushchih
ciklom i vyborom operatorov ($$R.6.4,$$R.6.5) i yavnye operacii
preobrazovaniya tipa ($$R.5.2.3, $$R.5.4).
   Pol'zovatel'skie preobrazovaniya primenyayutsya tol'ko v sluchae
ih odnoznachnosti ($$R.10.1.1, $$R.12.3.2). Preobrazovaniya prohodyat
proverku na sootvetstvie pravilam dostupa ($$R.11). Kak vsegda
proverka dostupa osushchestvlyaetsya posle razresheniya neodnoznachnosti
($$R.10.4).
    Primenenie preobrazovanij pri vyzove funkcii rassmatrivaetsya na
primerah, privedennyh nizhe, a takzhe obsuzhdaetsya v $$R.13.2.



Konstruktor, imeyushchij edinstvennyj parametr, zadaet preobrazovanie
tipa svoego fakticheskogo parametra v tip ego klassa, naprimer:

         class X {
           // ...
         public:
           X(int);
           X(const char*, int = 0);
         };

         void f(X arg) {
            X a = 1;        // a = X(1);
            X b = "Jessie"; // b = X("Jessie",0)
            a = 2;          // a = X(2)
            f(3);           // f(X(3))
         }

Esli v klasse X net konstruktora, kotoryj dopuskaet zadannyj tip,
ne delaetsya popytki najti kakoj-libo konstruktor drugogo klassa ili
funkciyu preobrazovaniya dlya privedeniya zadannogo znacheniya v znachenie
tipa,dopustimogo dlya konstruktora klassa X, naprimer:

         class X { /* ... */ X(int); };
         class Y { /* ... */ Y(X); };
         Y a = 1;        // nedopustimo: preobrazovanie Y(X(1))
                         // ne primenyaetsya



Funkciya-chlen klassa X, imya kotoroj imeet vid,

         imya-funkcii-preobrazovaniya:
             operator imya-tipa-preobrazovaniya

         imya-tipa-preobrazovaniya:
             spisok-specifikacij-tipa opt operaciya-ptr opt

zadaet preobrazovanie iz tipa X v tip, opredelyaemyj konstrukciej
imya-tipa-preobrazovaniya. Takie funkcii-chleny nazyvayutsya funkciyami
preobrazovaniya. V konstrukcii spisok-specifikacij-tipa nel'zya
opisyvat' klassy, perechisleniya i imena-typedef, a takzhe nel'zya
zadavat' tipy formal'nyh parametrov i tip vozvrashchaemogo znacheniya.
   Privedem primer:

          class X {
            // ...
          public:
            operator int();
          };

          void f(X a)
          {
            int i = int(a);
            i = (int)a;
            i = a;
           }

Zdes' vo vseh treh operatorah prisvaivaemoe znachenie budet
preobrazovyvat'sya s pomoshch'yu funkcii X::operator int(). Pol'zovatel'skie
preobrazovaniya ne ogranichivayutsya tol'ko ispol'zovaniem v prisvaivanii
i inicializacii, naprimer:

           void g(X a, X b)
           {
             int i = (a) ? 1+a : 0;
             int j = (a&&b) ? a+b : i;
             if (a) { // ...
             }
           }

   Operacii preobrazovaniya nasleduyutsya. Funkcii preobrazovaniya
mogut byt' virtual'nymi.
   K dannomu znacheniyu neyavno primenyaetsya ne bolee odnogo
pol'zovatel'skogo preobrazovaniya (s pomoshch'yu konstruktora ili funkcii
preobrazovaniya), naprimer:

     class X {
       // ...
     public:
       operator int();
     };

     class Y {
       // ...
     public:
       operator X();
     };

     Y a;
     int b = a;     // nedopustimo: preobrazovanie
                    // a.operator X().operator int() ne primenyaetsya
     int c = X(a);  // normal'no: a.operator X().operator int()

   Pol'zovatel'skie preobrazovaniya osushchestvlyayutsya neyavno tol'ko
pri uslovii ih odnoznachnosti. Funkciya preobrazovaniya proizvodnogo
klassa ne zakryvaet funkciyu preobrazovaniya bazovogo klassa, esli
tol'ko oni ne preobrazuyut k odnomu i tomu zhe tipu, naprimer:

           class X {
           public:
             // ...
             operator int();
           };

           class Y : public X {
           public:
             // ...
             operator void*();
           };

           void f(Y& a)
           {
             if (a) {  // oshibka: neodnoznachnost'
             }
           }



Destruktorom nazyvaetsya funkciya-chlen klassa cl s imenem ~cl, ona
ispol'zuetsya dlya unichtozheniya znachenij tipa cl neposredstvenno pered
unichtozheniem ob容kta, soderzhashchego ih. Destruktor ne imeet formal'nyh
parametrov i dlya nego nel'zya zadat' tip vozvrashchaemogo znacheniya
(dazhe void). Nel'zya primenyat' operaciyu vzyatiya adresa dlya destruktora.
Mozhno vyzyvat' destruktor dlya ob容ktov so specifikaciej const ili
volatile, no sam destruktor nel'zya opisyvat' s etimi specifikaciyami
($$R.9.3.1). Destruktor ne mozhet byt' i staticheskim.
    Destruktory ne nasleduyutsya. Esli bazovyj klass ili chlen imeyut
destruktor, a sam proizvodnyj klass - net, to sozdaetsya standartnyj
destruktor, kotoryj vyzyvaet destruktory bazovyh klassov i chlenov
proizvodnogo klassa. Takie sozdannye destruktory imeyut specifikaciyu
public.
    Telo destruktora vypolnyaetsya prezhde destruktorov dlya ob容ktov,
yavlyayushchihsya chlenami. Destruktory dlya nestaticheskih ob容ktov, yavlyayushchihsya
chlenami, vypolnyayutsya prezhde, chem destruktory dlya bazovyh klassov.
Destruktory dlya nevirtual'nyh bazovyh klassov vypolnyayutsya prezhde,
chem destruktory dlya virtual'nyh bazovyh klassov. Destruktory dlya
nevirtual'nyh bazovyh klassov vypolnyayutsya v poryadke, obratnom ih
opisaniyu v proizvodnom klasse. Destruktory virtual'nyh bazovyh
klassov vypolnyayutsya v poryadke, obratnom poyavleniyu ih pri obhode
snizu i sleva-napravo aciklichnogo napravlennogo grafa bazovyh
klassov. Zdes' "sleva-napravo" oznachaet poryadok poyavleniya imen
bazovyh klassov, kotoryj byl pri opisanii ih v proizvodnom klasse.
   Destruktory dlya elementov massiva vyzyvayutsya v poryadke,
obratnom vyzovam pri ih postroenii.
   Destruktor mozhet byt' virtual'nym.
   V destruktore mozhno vyzyvat' funkciyu-chlen, sm. $$R.12.7.
   Ob容kt klassa s destruktorom ne mozhet byt' chlenom ob容dineniya.
   Destruktory vyzyvayutsya neyavno v sleduyushchih sluchayah:
   (1) kogda ischezayut iz oblasti vidimosti ob容kty auto ($$R.3.5)
   ili vremennye ob容kty ($$R.12.2, $$R.8.4.3);
   (2) pri zavershenii programmy ($$R.3.4) dlya postroennyh staticheskih
   ob容ktov ($$R.3.5);
   (3) blagodarya obrashcheniyu k operacii delete ($$R.5.3.4) dlya ob容ktov,
   sozdannyh s pomoshch'yu operacii new ($$R.5.3.3);
   (4) pri yavnom vyzove.
Kogda destruktor vyzyvaetsya operaciej delete, to on osvobozhdaet
pamyat' dlya samogo bol'shego iz proizvodnyh klassov ($$R.12.6.2) togo
ob容kta, kotoryj ispol'zoval operaciyu delete() ($$R.5.3.4),
naprimer:

           class X {
             // ...
           public:
             X(int);
             ~X();
           };

           void g(X*);

           void f()     // obshchij sluchaj
           {
             X* p = new X(111);   // razmeshchenie i inicializaciya
             g(p);
             delete p;            // osvobozhdenie i udalenie
           }

YAvnye vyzovy destruktorov primenyayutsya redko. Primerom etogo mozhet
sluzhit' vyzov destruktora dlya ob容ktov, sozdannyh v nekotoroj
opredelennoj adresnoj oblasti s pomoshch'yu operacii new. Razmeshchenie
ob容ktov v opredelennom adresnom prostranstve i posleduyushchee
unichtozhenie ih mozhet potrebovat'sya dlya ispol'zovaniya specificheskih
vozmozhnostej apparatury i dlya pravil'nogo funkcionirovaniya operativnoj
pamyati. Privedem primer:

     void* operator new(size_t, void* p) { return p; }

     void f(X* p);

     static char buf[sizeof(X)];

     void g()     // redkij, special'nyj sluchaj
     {
       X* p = new(buf) X(222);  // razmeshchenie v buf[] i inicializaciya
       f(p);
       p->X::~X();              // udalenie
     }

  Oboznacheniya, ispol'zovannye dlya yavnogo vyzova destruktora, mozhno
ispol'zovat' dlya imeni lyubogo prostogo tipa, naprimer,

          int* p;
          // ...
          p->int::~int();

Ispol'zovanie takoj zapisi dlya tipa, u kotorogo net destruktora,
prohodit bessledno. Dopuskaya takuyu zapis', my razreshaem pol'zovatelyam
pisat' programmu, ne zadumyvayas' nad tem, est' li dannogo tipa
destruktor.



Kogda sozdaetsya ob容kt s pomoshch'yu operacii new, dlya polucheniya svobodnoj
pamyati vyzyvaetsya (neyavno) funkciya operator new() ($$R.5.3.3).
    Esli funkciya operator new() ne mozhet vypolnit' zapros, ona
vozvrashchaet 0.
    V klasse X funkciya X::operator new() yavlyaetsya staticheskim chlenom,
dazhe esli ona ne opisana yavno kak static. Pervyj ee parametr dolzhen
imet' tip size_t, - zavisyashchij ot realizacii celochislennyj tip,
kotoryj opredelen v standartnom zagolovochnom fajle <stddef.h>, i
ona dolzhna vozvrashchat' znachenie tipa void*, naprimer:

           class X {
             // ...
             void* operator new(size_t);
             void* operator new(size_t, Arena*);
           };

   Pravila vybora podhodyashchej funkcii operator new() obsuzhdayutsya
v $$R.5.3.3.
   V klasse X funkciya X::operator delete() yavlyaetsya staticheskim
chlenom, dazhe esli ona ne opisana yavno kak static. Pervyj ee parametr
dolzhen byt' tipa void* i mozhno dobavlyat' vtoroj parametr tipa
size_t. Ona ne mozhet vozvrashchat' kakoe-libo znachenie i tip
vozvrashchaemogo znacheniya dolzhen byt' void, naprimer:

           class X {
             // ...
             void operator delete(void*);
           };

           class Y {
             // ...
             void operator delete(void*, size_t);
           };

V kazhdom klasse mozhno opisat' tol'ko odnu funkciyu operator delete(),
znachit eta funkciya ne mozhet byt' peregruzhennoj. Global'naya funkciya
operator delete() imeet edinstvennyj parametr tipa void*.
   Esli funkciya opisana s dvumya formal'nymi parametrami, ona vyzyvaetsya
s dvumya parametrami, vtoroj iz kotoryh pokazyvaet razmer udalyaemogo
ob容kta. Peredavaemyj razmer opredelyaetsya s pomoshch'yu destruktora
(esli on est') ili po tipu (staticheskomu) ukazatelya na udalyaemyj
ob容kt. Operaciya projdet korrektno, esli tip ukazatelya, zadannogo
kak fakticheskij parametr, budet sovpadat' s tipom ob容kta (a ne budet,
k primeru, prosto tipom ukazatelya na bazovyj klass) ili, esli
etot tip yavlyaetsya tipom ukazatelya na bazovyj klass s virtual'nym
destruktorom.
   Dlya massivov ob容ktov tipa klass ispol'zuyutsya global'nye funkcii
operator new() i operator delete() ($$R.5.3.3, $$R.5.3.4).
   Poskol'ku funkcii X::operator new() i X::operator delete()
staticheskie, oni ne mogut byt' virtual'nymi. Funkciya
operator delete(), kotoraya vyzyvaetsya iz destruktora dlya osvobozhdeniya
pamyati, vybiraetsya po obychnym pravilam oblastej vidimosti,
naprimer:

           struct B {
             virtual ~B();
             void* operator new(size_t);
             void operator delete(void*);
           };

           struct D : B {
             ~D();
             void* operator new(size_t);
             void operator delete(void*);
           };

           void f()
           {
             B* p = new D;
             delete p;
           }

V etom primere pamyat' dlya ob容kta klassa D vydelyaetsya s pomoshch'yu
D::operator new(), a blagodarya nalichiyu virtual'nogo destruktora,
osvobozhdaetsya s pomoshch'yu D::operator delete().



Ob容kt klassa bez konstruktorov, bez chastnyh ili zashchishchennyh chlenov,
bez virtual'nyh funkcij i bez bazovyh klassov mozhno inicializirovat'
s pomoshch'yu spiska inicializatorov ($$R.8.4.1). Ob容kt klassa s
konstruktorom dolzhen inicializirovat'sya ili imet' standartnyj
konstruktor ($$R.12.1). Standartnyj konstruktor ispol'zuetsya dlya
ob容ktov, kotorye ne prohodyat yavnoj inicializacii.



Ob容kty klassov s konstruktorami ($$R.12.1) mozhno inicializirovat'
spiskom vyrazhenij, zaklyuchennym v skobki. |tot spisok schitaetsya
spiskom fakticheskih parametrov dlya vyzova konstruktora, proizvodyashchego
inicializaciyu. Inache, v kachestve inicializatora zadaetsya s pomoshch'yu
operacii = odno znachenie. Ono ispol'zuetsya kak fakticheskij parametr
dlya konstruktora kopirovaniya. Obychno mozhno obojtis' bez vyzova
konstruktora kopirovaniya, naprimer:

           class complex {
             // ...
           public:
             complex();
             complex(double);
             complex(double,double);
             // ...
           };

           complex sqrt(complex,complex);

           complex a(1);             // inicializaciya vyzovom
                                     // complex(double)
           complex b = a;            // inicializaciya kopirovaniem `a'
           complex c = complex(1,2); // konstruktor complex(1,2)
                                     // vyzyvaetsya complex(double,double)
                                     // i kopiruetsya v `c'
           complex d = sqrt(b,c);    // vyzyvaetsya sqrt(complex,complex),
                                     // rezul'tat kopiruetsya v `d'
           complex e;                // inicializaciya vyzovom konstruktora
           complex f = 3;            // complex(3), vyzyvaetsya
                                     // complex(double) i rezul'tat
                                     // kopiruetsya v `f'

Peregruzka operacii prisvaivaniya = ne okazyvaet vliyanie na
inicializaciyu.
   Inicializaciya, proishodyashchaya pri peredache fakticheskih parametrov
i pri vozvrate iz funkcii, ekvivalentna inicializacii vida

           T x = a;

Inicializaciya, proishodyashchaya v vyrazhenii operacii new ($$R.5.3.3) i
pri inicializacii bazovyh klassov i chlenov, ekvivalentna
inicializacii vida

           T x(a);

   Dlya massivov ob容ktov klassa s konstruktorami ispol'zuyutsya pri
inicializacii ($$R.12.1) konstruktory kak i dlya odinochnyh ob容ktov.
Esli okazalos', chto inicializatorov v spiske men'she, chem elementov
massiva, ispol'zuetsya standartnyj konstruktor ($$R.12.1). Esli ego
net, spisok inicializatorov dolzhen byt' polnym. Privedem primer:

           complex cc = { 1, 2 }; // oshibka: neobhodimo
                                  // ispol'zovat' konstruktor
           complex v[6] = { 1,complex(1,2),complex(),2 };

Zdes' v[0] i v[3] inicializiruyutsya znacheniem complex::complex(double),
v[1] inicializiruetsya complex::complex(double,double), a v[2],
v[4] i v[5] inicializirovany complex::complex().
   Ob容kt klassa M moet byt' chlenom klassa X v odnom iz sleduyushchih
sluchaev:
  (1) M ne imeet konstruktora;
  (2) M imeet standartnyj konstruktor;
  (3) X imeet konstruktor i kazhdyj iz nih zadaet inicializator-ctor
      ($$R.12.6.2) dlya chlena M.
V sluchae 2 pri sozdanii sostavnogo ob容kta vyzyvaetsya standartnyj
konstruktor. Esli chlen sostavnogo ob容kta imeet destruktor, to on
vyzyvaetsya pri unichtozhenii sostavnogo ob容kta.
   Konstruktory dlya nelokal'nyh staticheskih ob容ktov vyzyvayutsya v
tom poryadke, v kakom oni idut v tekste programmy, destruktory
vyzyvayutsya v obratnom poryadke, sm. takzhe $$R.3.4, $$R.6.7,
$$R.9.4.




V opredelenii konstruktora mozhno zadat' inicializaciyu pryamyh
bazovyh klassov i chlenov, ne nasleduemyh iz bazovyh klassov. |to
osobenno polezno dlya teh ob容ktov, konstant i ssylok, dlya kotoryh
razlichayutsya semantiki prisvaivaniya i inicializacii. Konstrukciya
inicializator-ctor imeet vid

           inicializator-ctor:
                : spisok-inicializatorov-chlenov

           spisok-inicializatorov-chlenov:
                inicializator-chlena
                inicializator-chlena , spisok-inicializatorov-chlena

           inicializator-chlena:
                polnoe-imya-klassa ( spisok-vyrazhenij opt )
                identifikator

Spisok parametrov ispol'zuetsya dlya inicializacii nestaticheskih chlenov
ili ob容ktov bazovogo klassa. |to edinstvennyj sposob inicializacii
nestaticheskih chlenov, yavlyayushchihsya ssylkami ili ob容ktami tipa const,
naprimer:

          struct B1 { B1(int); /* ... */ };
          struct B2 { B2(int); /* ... */ };

          struct D : B1, B2 {
              D(int);
              B1 b;
              const c;
          };

          D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4)
          { /* ... */ }
          D d(10);

  V nachale inicializiruyutsya bazovye klassy v poryadke ih opisaniya
(nezavisimo ot poryadka inicializatorov-chlenov), zatem po toj zhe
sheme inicializiruyutsya chleny, i nakonec vypolnyaetsya telo D::D()
($$R.12.1). Poryadok opisaniya vyderzhivaetsya dlya togo, chtoby garantirovat',
chto vlozhennye ob容kty i chleny budut unichtozhat'sya v poryadke, obratnom
ih inicializacii.
   Osobyj sluchaj predstavlyayut virtual'nye bazovye klassy. Oni sozdayutsya
prezhde, chem lyuboj nevirtual'nyj bazovyj klass i v tom zhe poryadke,
v kakom poyavlyayutsya pri obhode snizu i sleva-napravo aciklichnogo
napravlennogo grafa bazovyh klassov. Poryadok "sleva-napravo" - eto
tot, v kotorom imena bazovyh klassov zadayutsya pri opisanii v
proizvodnom klasse.
   Polnym nazyvaetsya ob容kt, kotoryj ne yavlyaetsya vlozhennym ob容ktom,
predstavlyayushchim nekotoryj bazovyj klass. Klass takogo ob容kta
nazyvayut naibol'shim proizvodnym klassom ob容kta. Vse vlozhennye
ob容kty virtual'nyh bazovyh klassov inicializiruyutsya s pomoshch'yu
konstruktora naibol'shego proizvodnogo klassa. Esli v konstruktore
naibol'shego proizvodnogo klassa ne zadan inicializator-chlena dlya
virtual'nogo bazovogo klassa, togda etot virtual'nyj bazovyj klass
dolzhen imet' standartnyj konstruktor,libo ne imet' nikakogo
konstruktora. Vsyakij inicializator-chlena dlya virtual'nogo bazovogo
klassa, zadannyj ne v konstruktore klassa polnogo ob容kta, ignoriruetsya.
Privedem primer:

           class V {
           public:
             V();
             V(int);
             // ...
           };

           class A : public virtual V {
           public:
             A();
             A(int);
             // ...
           };

           class B : public virtual V {
           public:
             B();
             B(int);
             // ...
           };

           class C : public A, public B, private virtual V {
           public:
             C();
             C(int);
             // ...
           };

           A::A(int i) : V(i) { /* ... */ }
           B::B(int i) { /* ... */ }
           C::C(int i) { /* ... */ }

           V v(1);  // use V(int)
           A a(2);  // use V(int)
           B b(3);  // use V()
           C c(4);  // use V()

   Inicializator-chlena vychislyaetsya v oblasti vidimosti konstruktora,
v kotorom on poyavilsya. Naprimer, v sleduyushchem fragmente

           class X {
             int a;
           public:
             const int& r;
             X()::r(a) { }
           };

X::r inicializiruetsya dlya kazhdogo ob容kta klassa X ssylkoj na X::a.



V konstruktorah i destruktorah mozhno vyzyvat' funkciyu-chlen. Otsyuda
sleduet, chto mozhno vyzyvat' (neposredstvenno ili kosvenno)
virtual'nye funkcii. Vyzyvaemaya funkciya dolzhna byt' opredelena
v klasse samogo konstruktora ili destruktora ili v bazovyh klassah,
no ne dolzhna byt' funkciej, kotoraya ih podavlyaet v proizvodnom klasse.
|tim obespechivaetsya to, chto eshche nesozdannye ob容kty ne budut
ispol'zovany pri vypolnenii konstruktora ili destruktora. Rassmotrim
primer:

            class X {
            public:
              virtual void f();
              X() { f(); }  // vyzov X::f()
              ~X() { f(); } // vyzov X::f()
            };

            class Y : public X {
              int& r;
            public:
              void f()
              {
                r++; // beda, esli `r' ne inicializirovano
              }
              Y(int& rr) ::r(rr) { }
            };

    Rezul'tat neposredstvennogo ili kosvennogo vyzova iz konstruktora
chistoj virtual'noj funkcii dlya inicializiruemogo ob容kta neopredelen,
esli tol'ko yavno ne ispol'zovano utochnenie imeni funkcii ($$R.10.3).



Ob容kty klassa mogut kopirovat'sya dvumya sposobami: libo prisvaivaniem
($$R.5.17), libo inicializaciej ($$R.12.1, $$R.8.4), kotoraya mozhet
proishodit' pri peredache parametrov ($$R.5.2.2) ili
rezul'tata funkcii ($$R.6.6.3). Dlya klassa X eti dve operacii
konceptual'no realizuyutsya kak operaciya prisvaivaniya i konstruktor
kopirovaniya ($$R.12.1). V programme mozhno opredelit' ili odnu iz nih,
ili obe. Esli pol'zovatel' ne opredelil ih v programme, to oni budut
dlya vseh chlenov klassa X opredelyat'sya sootvetstvenno kak prisvaivanie
po chlenam i inicializaciya po chlenam.
    Esli vse bazovye klassy i vse chleny klassa X imeyut konstruktor
kopirovaniya, v kotorom dopustimy v kachestve parametra ob容kty tipa
const, to porozhdaemyj konstruktor kopirovaniya dlya X budet imet'
edinstvennyj parametr tipa const X& i zapisyvat'sya tak:

           X::X(const X&)

    Inache, u nego budet edinstvennyj parametr tipa X&:

           X::X(X&)

i inicializaciya kopirovaniem ob容ktov tipa const klassa X budet
nevozmozhna.
   Analogichno, esli vse bazovye klassy i chleny klassa X imeyut
operaciyu prisvaivaniya, dopuskayushchuyu parametry tipa const, togda
porozhdaemaya dlya X operaciya prisvaivaniya budet imet' edinstvennyj
parametr tipa const X& i zapisyvat'sya tak:

           X& X::operator=(const X&)

    Inache, u nee budet edinstvennyj parametr tipa X&:

           X& X::operator=(X&)

i prisvaivanie kopirovaniem ob容ktov klassa X tipa const budet
nevozmozhno. Standartnaya operaciya prisvaivaniya vozvrashchaet ssylku
na ob容kt, kotoryj nuzhno bylo kopirovat'.
    Ob容kty, predstavlyayushchie virtual'nye bazovye klassy, budut
inicializirovat'sya tol'ko odin raz s pomoshch'yu porozhdaemogo
konstruktora kopirovaniya. Ob容kty, predstavlyayushchie virtual'nye
bazovye klassy, dopuskayut prisvaivaniya im tol'ko odin raz s pomoshch'yu
porozhdaemoj operacii prisvaivaniya.
    Prisvaivanie po chlenam i inicializaciya po chlenam oznachayut
sleduyushchee: esli klass X imeet v kachestve chlena klass M, dlya realizacii
prisvaivaniya i inicializacii chlena ispol'zuyutsya operacii prisvaivaniya
v M i konstruktor kopirovaniya M sootvetstvenno. Esli klass imeet
chlen tipa const, ili chlen, yavlyayushchijsya ssylkoj, ili chlen ili bazovyj
klass takogo klassa, gde funkciya operator=() yavlyaetsya chastnoj,
to dlya nego standartnaya operaciya prisvaivaniya ne mozhet byt' sozdana.
Analogichno, esli chlen ili bazovyj klass klassa M imeet chastnyj
konstruktor kopirovaniya, to standartnyj konstruktor kopirovaniya dlya
takogo klassa ne mozhet byt' sozdan.
    Poka ne poyavitsya neobhodimost' v opredelenii, standartnye prisvaivanie
i konstruktor kopirovaniya budut tol'ko opisany (t.e. ne budet sozdano
telo funkcii). Inymi slovami, funkciya X::operator=() budet porozhdena
tol'ko togda, kogda net yavnogo opisaniya operacij prisvaivaniya, a ob容kt
klassa X prisvaivaetsya ob容ktu klassa X ili ob容ktu klassa, proizvodnogo
ot X, ili vychislyaetsya adres funkcii X::operator=(). Analogichnaya situaciya
s inicializaciej.
    Esli prisvaivanie i konstruktor kopirovaniya opisany neyavno, to
oni budut obshchimi funkciyami-chlenami i operaciya prisvaivaniya dlya klassa
X opredelyaetsya takim obrazom, chto ee rezul'tatom yavlyaetsya ssylka
tipa X& na ob容kt, kotoromu prisvaivayut.
    Esli v klasse X est' funkciya X::operator=(), parametrom kotoroj
yavlyaetsya sam klass X, to standartnoe prisvaivanie ne budet
porozhdat'sya. Esli v klasse opredelen kakoj-libo konstruktor
kopirovaniya, to standartnyj konstruktor kopirovaniya ne budet
porozhdat'sya. Privedem primer:

         class X {
           // ...
         public:
           X(int);
           X(const X&, int = 1);
         };

         X a(1);     // vyzov X(int)
         X b(a,0);   // vyzov X(const X&,int)
         X c = b;    // vyzov X(const X&,int)

    Prisvaivanie ob容ktov klassa X opredelyaetsya cherez funkciyu
X::operator=(const X&). |to oznachaet ($$R.12.3), chto ob容kty
proizvodnogo klassa mozhno prisvaivat' ob容ktam obshchego bazovogo
klassa, naprimer:

         class X {
         public:
           int b;
         };

         class Y : public X {
         public:
           int c;
         };

         void f()
         {
           X x1;
           Y y1;
           x1 = y1;  // normal'no
           y1 = x1;  // oshibka
         }

  V etom primere y1.b prisvaivaetsya x1.b, a x1.c ne kopiruetsya.
    Kopirovanie odnogo ob容kta v drugoj s pomoshch'yu standartnoj
operacii kopirovaniya ili standartnogo konstruktora kopirovaniya
ne izmenyaet strukturu oboih ob容ktov. Privedem primer:

          struct s {
            virtual f();
            // ...
          };

          struct ss : public s {
            f();
            // ...
          };

          void f()
          {
            s a;
            ss b;
            a = b;     // na samom dele vypolnyaetsya a.s::operator=(b)
            b = a;     // oshibka
            a.f();     // vyzov s::f
            b.f();     // vyzov ss::f
            (s&)b = a; // prisvaivanie a  b
                       // na samom dele vypolnyaetsya ((s&)b).s::operator=(a)
            b.f();     // vse eshche vyzov ss::f
          }

Vyzov a.f() privedet k vyzovu s::f() (kak i dolzhno byt' dlya ob容kta
klassa s ($$R.10.2)), a vyzov b.f() privedet k vyzovu ss::f()
( kak i dolzhno byt' dlya ob容kta klassa ss).



Govoryat, chto imya peregruzheno, esli dlya nego zadano neskol'ko razlichnyh
opisanij funkcij v odnoj oblasti vidimosti. Pri ispol'zovanii imeni
vybor pravil'noj funkcii proizvoditsya putem sopostavleniya tipov
formal'nyh parametrov s tipami fakticheskih parametrov, naprimer:

          double abs(double);
          int abs(int);

           abs(1);   // vyzov abs(int)
           abs(1.0); // vyzov abs(double)

Poskol'ku pri lyubom tipe T i dlya samogo T , dlya i T& dopustimo odno i
to zhe mnozhestvo inicializiruyushchih znachenij, funkcii, tipy parametrov
kotoryh razlichayutsya tol'ko ispol'zovaniem, ili ne ispol'zovaniem
ssylki, ne mogut imet' odinakovye imena, naprimer:

           int f(int i)
           {
             // ...
            }

            int f(int& r)  // oshibka: tipy funkcij
            {              // nedostatochno razlichny
              // ...
             }

Analogichno, poskol'ku dlya lyubom tipe T dlya samogo T, const T i
volatile T dopustimo odno i to zhe mnozhestvo inicializiruyushchih
znachenij, funkcii, tipy parametrov kotoryh otlichayutsya tol'ko
ukazannoj specifikaciej, ne mogut imet' odinakovye imena. Odnako,
razlichit' const T&, volatile T& i prosto T& mozhno, poetomu dopustimy
opredeleniya funkcij s odnim imenem, kotorye razlichayutsya tol'ko
v ukazannom otnoshenii. Analogichno, dopustimy opredeleniya funkcij
s odnim imenem, tipy parametrov kotoryh razlichayutsya tol'ko kak
tipy vida const T*, volatile T* i prosto T*.
   Ne mogut imet' odinakovye imena funkcii, kotorye otlichayutsya
tol'ko tipom vozvrashchaemogo znacheniya.
   Ne mogut imet' odinakovye imena funkcii-chleny, odna iz kotoryh
staticheskaya, a drugaya net ($$R.9.4).
   S pomoshch'yu konstrukcii typedef ne sozdayutsya novye tipy,
a tol'ko opredelyaetsya sinonim tipa ($$R.7.1.3), poetomu funkcii,
kotorye otlichayutsya tol'ko za schet ispol'zovaniya tipov, opredelennyh s
pomoshch'yu typedef, ne mogut imet' odinakovye imena. Privedem
primer:

        typedef int Int;

        void f(int i) { /* ... */ }
        void f(Int i) { /* ... */ } // oshibka: pereopredelenie f

S drugoj storony vse perechisleniya schitayutsya raznymi tipami, i s ih
pomoshch'yu mozhno razlichit' peregruzhennye funkcii, naprimer:

        enum E { a };

        void f(int i) { /* ... */ }
        void f(E i)   { /* ... */ }

   Tipy parametrov, kotorye razlichayutsya tol'ko tem, chto v odnom
ispol'zuetsya ukazatel' *, a v drugom massiv [], schitayutsya identichnymi.
Napomnim, chto dlya tipa parametra vazhny tol'ko vtoroj i posleduyushchie
indeksy mnogomernogo massiva ($$R.8.2.4). Podtverdim skazannoe
primerom:

        f(char*);
        f(char[]);       // identichno f(char*);
        f(char[7]);      // identichno f(char*);
        f(char[9]);      // identichno f(char*);
        g(char(*)[10]);
        g(char[5][10]);  // identichno g(char(*)[10]);
        g(char[7][10]);  // identichno g(char(*)[10]);
        g(char(*)[20]);  // otlichno ot g(char(*)[10]);



Dva opisaniya funkcij s odinakovymi imenami otnosyatsya k odnoj i toj
zhe funkcii, esli oni nahodyatsya v odnoj oblasti vidimosti i imeyut
identichnye tipy parametrov ($$R.13). Funkciya-chlen proizvodnogo
klassa otnositsya k inoj oblasti vidimosti, chem funkciya-chlen
bazovogo klassa s tem zhe imenem. Rassmotrim primer:

        class B {
        public:
          int f(int);
        };

        class D : public B {
        public:
          int f(char*);
        };

Zdes' D::f(char*) skoree skryvaet B::f(int), chem peregruzhaet etu
funkciyu.

        void h(D* pd)
        {
          pd->f(1);     // oshibka: D::f(char*) skryvaet B::f(int)
          pd->B::f(1);  // normal'no
          pd->f("Ben"); // normal'no, vyzov D::f
        }

Funkciya, opisannaya lokal'no, nahoditsya v inoj oblasti vidimosti, chem
funkciya s fajlovoj oblast'yu vidimosti.

        int f(char*);
        void g()
        {
          extern f(int);
          f("asdf");  // oshibka: f(int) skryvaet f(char*) poetomu
                      // v tekushchej oblasti vidimosti net f(char*)
        }

   Dlya raznyh variantov peregruzhennoj funkcii-chlena mozhno zadat'
raznye pravila dostupa, naprimer:

         class buffer {
         private:
           char* p;
           int size;

         protected:
           buffer(int s, char* store) { size = s; p = store; }
           // ...

         public:
           buffer(int s) { p = new char[size = s]; }
         };



Pri vyzove funkcii s dannym imenem proishodit vybor iz vseh
funkcij s etim imenem, kotorye nahodyatsya v tekushchej oblasti vidimosti, i
dlya kotoryh sushchestvuyut preobrazovaniya tipa, delayushchie vyzov vozmozhnym.
Vybiraetsya ta funkciya, kotoraya naibolee sootvetstvuet fakticheskim
parametram. Ona nahoditsya v oblasti peresecheniya mnozhestv
funkcij, kazhdoe iz kotoryh naibolee sootvetstvuyut vyzovu po dannomu
fakticheskomu parametru. Operaciya vyzova schitaetsya dopustimoj, esli v etom
peresechenii nahoditsya tol'ko odin chlen. Funkciya, vybrannaya takim obrazom,
dolzhna bolee lyuboj drugoj funkcii s tem zhe imenem sootvetstvovat'
vyzovu, hotya by po odnomu iz parametrov (neobyazatel'no eto
budet odin i tot zhe parametr dlya raznyh funkcij). V protivnom sluchae,
vyzov schitaetsya nedopustimym.
    Pri sopostavlenii parametrov rassmatrivayut funkciyu s chislom
standartnyh znachenij parametrov ($$R.8.2.6), ravnym n, kak
n+1 funkcij s razlichnym chislom parametrov.
   Pri sopostavlenii parametrov nestaticheskuyu funkciyu-chlen
rassmatrivayut kak funkciyu, imeyushchuyu dopolnitel'nyj parametr,
ukazyvayushchij na ob容kt, dlya kotorogo vyzyvaetsya funkciya. |tot
dopolnitel'nyj formal'nyj parametr dolzhen sopostavlyat'sya ili
s ob容ktom, ili s ukazatelem na ob容kt, zadannymi v yavnoj operacii
vyzova funkcii-chlena ($$R.5.2.4), ili zhe s pervym operandom
peregruzhennoj funkcii operator ($$R.13.4). Dlya etogo dopolnitel'nogo
parametra ne ispol'zuetsya nikakih vremennyh ob容ktov, a dlya dostizheniya
sopostavleniya ne proizvoditsya nikakih pol'zovatel'skih preobrazovanij
tipa.
   Esli yavno vyzyvaetsya chlen klassa X, ispol'zuya ukazatel' i operaciyu
->, to schitaetsya, chto dopolnitel'nyj parametr imeet tip const* X dlya
chlenov tipa const, volatile* X dlya chlenov tipa volatile i
X* dlya vseh ostal'nyh chlenov. Esli yavno vyzyvaetsya funkciya-chlen,
ispol'zuya ob容kt i operaciyu ., a takzhe, esli  vyzyvaetsya funkciya
dlya pervogo operanda peregruzhennoj funkcii operator ($$R.9.4),
to schitaetsya, chto dopolnitel'nyj parametr imeet tip: const X& dlya
chlenov tipa const, volatile X& dlya chlenov tipa volatile i  X&
dlya vseh ostal'nyh chlenov. Pervyj operand dlya ->* i .* rassmatrivaetsya
tak zhe, kak i pervyj operand dlya -> i . sootvetstvenno.
   |llipsis v spiske formal'nyh parametrov ($$R.8.2.5) mozhet
sopostavlyat'sya s fakticheskim parametrom lyubogo tipa.
   Dlya dannogo fakticheskogo parametra dopuskaetsya tol'ko takaya
posledovatel'nost' preobrazovanij tipa, kotoraya soderzhit ne bolee
odnogo pol'zovatel'skogo preobrazovaniya. Ee nel'zya sokratit',
isklyuchiv odno ili neskol'ko preobrazovanij, do posledovatel'nosti,
kotoraya takzhe privodit k tipu, sopostavimomu s tipom rassmatrivaemogo
formal'nogo parametra. Takaya posledovatel'nost' preobrazovanij
nazyvaetsya naibolee sootvetstvuyushchej posledovatel'nost'yu.
   Naprimer, posledovatel'nost' int->float->double zadaet
preobrazovanie int v double, no ee nel'zya nazvat' naibolee
sootvetstvuyushchej posledovatel'nost'yu, poskol'ku v nej soderzhitsya
bolee korotkaya posledovatel'nost' int->double.
    Krome opisannyh nizhe sluchaev, sleduyushchie trivial'nye
preobrazovaniya  tipa T ne vliyayut na svojstvo posledovatel'nosti
byt' naibolee sootvetstvuyushchej:

       ishodnyj tip      tip rezul'tata
           T                 T&
           T&                T
           T[]               T*
           T(parametry)      T(*)(parametry)
           T                 const T
           T                 volatile T
           T*                const T*
           T*                volatile T*

Posledovatel'nosti trivial'nyh preobrazovanij, kotorye otlichayutsya
tol'ko poryadkom preobrazovanij, schitayutsya sovpadayushchimi. Otmetim,
chto dlya funkcij s formal'nym parametrom tipa T, const T, volatile T,
T&, const T& i volatile T& dopustim fakticheskij parametr iz odno i
togo zhe mnozhestva znachenij. Pri neobhodimosti dlya razdeleniya
posledovatel'nostej preobrazovanij ispol'zuyutsya specifikacii const i
volatile, kak opisano v pravile [1] nizhe.
   Dlya formal'nogo parametra tipa T& trebuetsya vremennaya peremennaya
v sluchayah, esli: fakticheskij parametr ne yavlyaetsya adresom, ili imeet tip,
otlichnyj ot T, v tom chisle tip volatile. Nalichie takoj peremennoj
ne vliyaet na sopostavlenie parametrov. Odnako, ono mozhet povliyat'
na dopustimost' rezul'tata sopostavleniya, t.k. vremennuyu peremennuyu
nel'zya ispol'zovat' dlya inicializacii ssylok, ne yavlyayushchihsya
const ($$R.8.4.3).
   Posledovatel'nosti preobrazovanij rassmatrivayutsya soglasno
sleduyushchim pravilam:
   [1] Tochnoe sopostavlenie. Posledovatel'nosti iz nulya ili bolee
       trivial'nyh preobrazovanij predpochtitel'nee lyubyh drugih
       posledovatel'nostej. Iz bolee slozhnyh posledovatel'nostej
       naibolee predpochtitel'ny te, v kotoryh net preobrazovanij
       T* v const T*, T* v volatile T*, T& v const T& ili
       T& v volatile T&.
   [2] Sopostavlenie so standartnymi preobrazovaniyami osnovnyh tipov.
       Iz posledovatel'nostej, ne otnosyashchihsya k [1], naibolee
       predpochtitel'ny te, kotorye soderzhat tol'ko standartnye
       celochislennye preobrazovaniya ($$R.4.1),
       preobrazovaniya float v double i trivial'nye preobrazovaniya.
   [3] Sopostavlenie s lyubymi standartnymi preobrazovaniyami.
       iz posledovatel'nostej, ne otnosyashchihsya k [2], naibolee
       predpochtitel'ny te, kotorye soderzhat tol'ko lyubye
       standartnye preobrazovaniya ($$R.4.1, $$R.4.2, $$R.4.3, $$R.4.4,
       $$R.4.5, $$R.4.6, $$R.4.7, $$R.4.8) i trivial'nye
       preobrazovaniya. Dlya etih posledovatel'nostej esli A yavlyaetsya
       pryamym ili kosvennym obshchim bazovym dlya klassa B,
       to preobrazovanie B* v A* predpochtitel'nee preobrazovaniya B*
       v void* ili const void*. Dalee, esli B yavlyaetsya pryamym ili
       kosvennym bazovym klassom dlya C, to predpochtitel'nee preobrazovanie
       C* v B*, chem C* v A*, i predpochtitel'nee preobrazovanie C& v B&,
       chem C& v A&. Ierarhiya klassov vystupaet zdes' kriterij otbora
       preobrazovanij ukazatelya v chlen ($$R.4.8).
   [4] Sopostavlenie s pol'zovatel'skimi preobrazovaniyami.
       Iz posledovatel'nostej, ne otnosyashchihsya k [3], naibolee
       predpochtitel'ny te, kotorye soderzhat tol'ko
       pol'zovatel'skie ($$R.12.3), standartnye ($$R.4) i trivial'nye
       preobrazovaniya.
   [5] Sopostavlenie s ellipsisom.
       Posledovatel'nosti, kotorye trebuyut sopostavleniya s ellipsisom,
       schitayutsya naimenee predpochtitel'nymi.
   Pol'zovatel'skie preobrazovaniya vybirayut, ishodya iz tipa
peremennoj, kotoraya inicializiruetsya ili kotoroj prisvaivaetsya
znachenie.

        class Y {
          // ...
        public:
          operator int();
          operator double();
        };

        void f(Y y)
        {
          int i = y;    // vyzov Y::operator int()
          double d;
          d = y;        // vyzov Y::operator double()
          float f = y;  // oshibka: neodnoznachnost'
        }

  Standartnye preobrazovaniya ($$R.4) mogut primenyat'sya k parametru,
kak do pol'zovatel'skogo preobrazovaniya, tak i posle nego.

        struct S { S(long); operator int(); };

        void f(long), f(char*);
        void g(S), g(char*);
        void h(const S&), h(char*);

        void k(S& a)
        {
          f(a);    // f(long(a.operator int()))
          g(1);    // g(S(long(1)))
           h(1);   // h(S(long(1)))
        }

Esli dlya parametra trebuetsya pol'zovatel'skoe preobrazovanie, to ne
uchityvayutsya nikakie standartnye preobrazovaniya, kotorye mogut
zatragivat' etot parametr, naprimer:

        class x {
        public:
           x(int);
        };

        class y {
        public:
           y(long);
        };

        void f(x);
        void f(y);

        void g()
        {
          f(1);  // neodnoznachnost'
        }

Zdes' vyzov f(1) neodnoznachen. Nesmotrya na to, chto dlya vyzova
f(y(long(1))) trebuetsya na odno standartnoe preobrazovanie bol'she,
chem dlya vyzova f(x(1)), vtoroj vyzov ne yavlyaetsya predpochtitel'nym.
   Preobrazovaniya s pomoshch'yu konstruktora ($$R.12.1) i s pomoshch'yu
funkcii preobrazovaniya ($$R.12.3.2) ravnopravny.

        struct X {
          operator int();
        };

        struct Y {
          Y(X);
        };

        Y operator+(Y,Y);

        void f(X a, X b)
        {
           a+b;  // oshibka, neodnoznachnost':
                 //   operator+(Y(a), Y(b)) ili
                 //   a.operator int() + b.operator int()
        }



Kogda funkciya s nekotorym imenem ispol'zuetsya bez parametrov, sredi
vseh funkcij s takim imenem v tekushchej oblasti vidimosti vybiraetsya
edinstvennaya, kotoraya tochno sootvetstvuet naznacheniyu. Naznacheniem
mozhet byt':
       inicializiruemyj ob容kt ($$R.8.4);
       levaya chast' operacii prisvaivaniya ($$R.5.17);
       formal'nyj parametr funkcii ($$R.5.2.2);
       formal'nyj parametr pol'zovatel'skoj operacii ($$R.13.4);
       tip znacheniya, vozvrashchaemogo funkciej ($$R.8.2.5).
  Otmetim, chto esli f() i g() yavlyayutsya peregruzhennymi funkciyami, to
dlya pravil'noj interpretacii f(&g) ili ekvivalentnogo vyrazheniya
f(g) nuzhno rassmotret' peresechenie mnozhestv vybora dlya f() i g().
Privedem primer:

       int f(double);
       int f(int);
       int (*pfd)(double) = &f;
       int (*pfi)(int) = &f;
       int (*pfe)(...) = &f;   // oshibka: nesootvetstvie tipov

Poslednyaya inicializaciya oshibochna, ne iz-za neodnoznachnosti, a
potomu, chto ne opredeleno ni odnoj funkcii f() tipa int(...).
   Otmetim, chto ne sushchestvuet nikakogo standartnogo preobrazovaniya
($$R.4) ukazatelya na funkciyu odnogo tipa v ukazatel' na funkciyu
drugogo tipa ($$R.4.6). V chastnosti, dazhe esli B yavlyaetsya obshchim
bazovym klassom D, dve sleduyushchie inicializacii nedopustimy:

       D* f();
       B* (*p1)() = &f;     // oshibka

       void g(D*);
       void (*p2)(B*) = &g; // oshibka



Peregruzhat' mozhno bol'shinstvo operacij.

     imya-funkcii-operator:
         operator operaciya

     operaciya: odin iz
               new delete
               +   -   *   /   %   ^   &   |   ~
               !   =   <   >   +=  -=  *=  /=  %=
               ^=  &=  |=  <<  >>  >>= <<= ==  !=
               <=  >=  &&  ||  ++  --  ,   ->* ->
               ()  []

Dve poslednie operacii - eto vyzov funkcii ($$R.5.2.2) i indeksaciya
($$R.5.2.1).
    Mozhno peregruzhat' sleduyushchie (kak binarnye, tak i unarnye)
operacii:

            +  -  *  &

    Nel'zya peregruzhat' sleduyushchie operacii:

          .  .*  ::  ?:  sizeof

a takzhe i special'nye simvoly preprocessora # i ## ($$R.16).
  Obychno funkcii, zadayushchie operacii (funkciya-operator) ne vyzyvayutsya
yavno, k nim obrashchayutsya dlya vypolneniya operacij ($$R.13.4.1, $$R.13.4.2).
Odnako, k nim mozhno obrashchat'sya yavno, naprimer:

         complex z = a.operator+(b);  // complex z = a+b
         void* p = operator new(sizeof(int)*n);

  Operacii new i delete opisany v $$R.5.3.3 i $$R.5.3.4 i k nim
ne otnosyatsya perechislyaemye nizhe pravila.
  Funkciya-operator mozhet byt' funkciej-chlenom ili imet' po krajnej
mere odin parametr tipa klass ili ssylka na klass. Nel'zya izmenit'
prioritet, poryadok vypolneniya ili chislo operandov operacii, no
mozhno izmenit' predopredelennoe naznachenie takih operacij:  =,
unarnaya & i ,(zapyatoj), esli oni primenyayutsya k ob容ktu tipa klass.
Za isklyucheniem funkcii operator=(), funkciya-operator nasleduetsya.
Pravila dlya operator=() dany v $$R.12.8.
   |kvivalentnost' nekotoryh operacij nad osnovnymi tipami
(naprimer, ++a ekvivalentno a+=1) mozhet ne sohranyat'sya dlya takih
zhe operacij nad klassami. Dlya nekotoryh operacij trebuetsya, chtoby
v sluchae ispol'zovaniya osnovnyh tipov operand byl adresom (naprimer,
dlya +=). |to trebovanie mozhet byt' snyato, esli operaciya zadana nad
klassami.
   Peregruzhennaya operaciya ne mozhet imet' standartnye znacheniya
parametrov ($$R.8.2.6).
   Operacii, kotorye yavno ne ukazany v $$R.13.4.3-$$R.13.4.7,
dejstvuyut kak obychnye unarnye ili binarnye operacii, podchinyayushchiesya
pravilam, privedennym v $$R.13.4.1 ili $$R.13.4.2.



Prefiksnuyu unarnuyu operaciyu mozhno zadat' s pomoshch'yu nestaticheskoj
funkcii-chlena ($$R.9.3), bez parametrov ili s pomoshch'yu
funkcii, ne yavlyayushchejsya chlenom, s odnim parametrom. Takim obrazom,
dlya vsyakoj prefiksnoj unarnoj operacii @, vyrazhenie @x mozhet
interpretirovat'sya kak x.operator@() ili kak operator@(x).
Esli opisany funkcii-operatory oboih vidov, to kakaya iz nih budet
ispol'zovat'sya pri vyzove, opredelyaetsya pravilami sopostavleniya
parametrov ($$R.13.2). Postfiksnye unarnye operacii, takie kak ++ i -- ,
ob座asnyayutsya v $$R.13.4.7.



Binarnuyu operaciyu mozhno zadat' s pomoshch'yu nestaticheskoj
funkcii-chlena ($$R.9.3), imeyushchej odin parametr, ili s pomoshch'yu
funkcii, ne yavlyayushchejsya chlenom, s dvumya parametrami. Takim obrazom,
dlya vsyakoj binarnoj operacii @ vyrazhenie x@y mozhet interpretirovat'sya
kak x.operator@(y) ili kak operator@(x,y). Esli opisany
funkcii-operatory oboih vidov, to kakaya iz nih budet ispol'zovat'sya
pri vyzove, opredelyaetsya pravilami sopostavleniya parametrov ($$R.13.2).



Funkciya prisvaivaniya operator=() dolzhna byt' nestaticheskoj
funkciej-chlenom. Ona ne nasleduetsya ($$R.12.8). Bolee togo, esli
pol'zovatel' ne opredelil dlya klassa X funkciyu operator=, to
ispol'zuetsya standartnaya funkciya operator=, kotoraya opredelyaetsya
kak prisvaivanie po chlenam dlya klassa X.

     X& X::operator=(const X& from)
     {
         // kopirovanie po chlenam X
     }



Vyzov funkcii est' konstrukciya vida:
        pervichnoe-vyrazhenie ( spisok-vyrazhenij opt )
Ona schitaetsya binarnoj operaciej, v kotoroj pervichnoe-vyrazhenie
predstavlyaet pervyj operand, a spisok-vyrazhenij (vozmozhno pustoj),
- vtoroj operand. Imenem, zadayushchim funkciyu, sluzhit operator(), i vyzov
x(arg1,arg2,arg3) dlya ob容kta klassa x interpretiruetsya kak
x.operator()(arg1,arg2,arg3). Funkciya operator() dolzhna byt'
nestaticheskoj funkciej-chlenom klassa x.



Indeksaciya, opredelyaemaya kak:
       pervichnoe-vyrazhenie [ vyrazhenie ]
schitaetsya binarnoj operaciej. Vyrazhenie s indeksaciej x[y] dlya ob容kta
klassa x interpretiruetsya kak x.operator[](y). Funkciya operator[]
dolzhna byt' nestaticheskoj funkciej-chlenom klassa x.



Dostup k chlenu klassa opredelyaetsya s pomoshch'yu operacii ->:
       pervichnoe-vyrazhenie -> pervichnoe-vyrazhenie
On schitaetsya unarnoj operaciej. Dlya ob容kta klassa x vyrazhenie x->m
interpretiruetsya kak (x.operator->())->m. Otsyuda sleduet, chto
funkciya operator->() dolzhna vozvrashchat' ili ukazatel' na klass, ili
ssylku na klass, ili ob容kt klassa, dlya kotorogo opredelena funkciya
operator->(). Ona dolzhna byt' nestaticheskoj funkciej-chlenom klassa.



Funkciya s imenem operator++ i s odnim parametrom zadaet dlya ob容ktov
nekotorogo klassa operaciyu prefiksnogo inkrementa ++. Funkciya s
imenem operator++  i s dvumya parametrami zadaet dlya ob容ktov
nekotorogo klassa operaciyu postfiksnogo inkrementa ++. Dlya postfiksnoj
operacii ++ vtoroj parametr dolzhen byt' tipa int, i,
kogda v vyrazhenii vstrechaetsya operaciya postfiksnogo inkrementa,
funkciya operator++ vyzyvaetsya so vtorym parametrom, ravnym nulyu.
Privedem primer:

         class X {
         public:
           X operator++();   // prefiksnaya ++a
           X operator++(int) // postfiksnaya a++
         };

         void f(X a)
         {
           ++a;    // a.operator++();
           a++;    // a.operator++(0);

           a.operator++();  // yavnyj vyzov: dejstvuet kak ++a;
           a.operator++(0); // yavnyj vyzov: dejstvuet kak a++;
         }

   Prefiksnye i postfiksnye operacii dekrementa -- opredelyayutsya
analogichnym obrazom.


 R.14 SHABLONY TIPA

 R.14.1 SHablony tipa

 SHablon tipa opredelyaet celoe semejstvo tipov ili funkcij.

        opisanie-shablona-tipa:
           template < spisok-parametrov-shablona-tipa> opisanie

        spisok-parametrov-shablona-tipa:
             parametr-shablona-tipa
             spisok-parametrov-shablona-tipa , parametr-shablona-tipa

        parametr-shablona-tipa:
             parametr-tipa
             opisanie-parametra

        parametr-tipa:
             class identifikator

Konstrukciya opisanie v opisanii-shablona-tipa dolzhna soderzhat'
opisanie ili opredelenie funkcii ili klassa.
  V konstrukcii parametr-tipa identifikator opredelyaetsya kak imya-tipa
v oblasti vidimosti opisaniya shablona tipa.
  Imena shablonov tipa podchinyayutsya obychnym pravilam dlya oblastej
vidimosti i kontrolya dostupa. Konstrukciya opisanie-shablona-tipa
schitaetsya opisaniem. Ona mozhet prisutstvovat' v programme tol'ko
kak global'noe opisanie.



SHablon tipa dlya klassa opredelyaet kak budut stroit'sya  klassy,  podobno
tomu, kak opisanie klassa opredelyaet kak budut stroit'sya ob容kty etogo
klassa. SHablon tipa dlya klassa vector mozhno opisat' sleduyushchim obrazom:

          template<class T> class vector {
             T* v;
             int sz;
          public:
             vector(int);
             T& operator[](int);
             T& elem(int i) { return v[i] }
             // ...
          };

Prefiks template<class T> pokazyvaet, chto opisyvaetsya shablon tipa,
i chto v etom opisanii ispol'zuetsya imya-tipa T, inymi slovami,
vector - eto parametrizovannyj tip s parametrom T.
   Klass mozhno zadat' s pomoshch'yu konstrukcii imya-shablonnogo-klassa:
         imya-shablonnogo-klassa:
             imya-shablona-tipa < spisok-param-shablona-tipa >

         spisok-param-shablona-tipa:
             param-shablona-tipa
             spisok-param-shablona-tipa , param-shablona-tipa

         param-shablona:
             vyrazhenie
             imya-tipa
   Konstrukciya imya-shablonnogo-klassa  yavlyaetsya imenem-klassa ($$R.9).
   Klass, kotoryj porozhdaetsya shablonom tipa dlya klassa, nazyvaetsya
shablonnym klassom i ekvivalenten obychnomu klassu, opredelennomu so
special'nym imenem - imenem-shablonnogo-klassa, sm. $$R.14.5.
   Esli v konstrukcii imya-shablonnogo-klassa imya-shablona-tipa ne opredeleno,
to ona oboznachaet neopredelennyj klass.
   Imya shablonnogo klassa dolzhno byt' unikal'nym v programme i v svoej
oblasti vidimosti ono ne mozhet oboznachat' drugoj shablon tipa,
klass, funkciyu, ob容kt, znachenie ili tip.
   Tipy, ukazannye v spiske-param-shablona-tipa iz
imeni-shablonnogo-klassa, dolzhny sootvetstvovat' tipam, zadannym
v spiske-parametrov-shablona-tipa iz shablona-tipa. (Mozhno skazat',
chto pervye yavlyayutsya fakticheskimi parametrami shablona tipa, a vtorye
- formal'nymi.)
   Krome tipov v spiske-param-shablona-tipa mogut byt':
vyrazheniya-konstanty, adresa ob容ktov ili funkcij, podlezhashchih vneshnemu
svyazyvaniyu, staticheskie chleny klassov. Dlya parametrov, ne
yavlyayushchihsya tipami, trebuetsya tochnoe sootvetstvie ($$R.13.2).
   Privedem primery ispol'zovaniya klassov shablona tipa vector:

          vector<int> v1(20);
          vector<complex> v2(30);

          typedef vector<complex> cvec; // cvec stanovitsya sinonimom
                                        // vector<complex>
          cvec v3(40);  // v2 i v3 odnogo tipa

          v1[3] = 7;
          v2[3] = v3.elem(4) = complex(7,8);

  Zdes' vector<int> i vector<complex> yavlyayutsya shablonnymi klassami,
i ih opredeleniya berutsya po umolchaniyu iz shablona tipa vector.
  Poskol'ku shablonnoe-imya-klassa yavlyaetsya imenem-klassa, to ono mozhet
ispol'zovat'sya tam, gde dopustimo imya-klassa, naprimer:

          class vector<Shape*>

          vector<Window>* current_window;

          class svector : public vector<Shape*> { /* ... */ };

  Opredelenie funkcii-chlena shablonnogo klassa dano v $$R.14.6.



Dve konstrukcii shablonnoe-imya-klassa oboznachayut odin i tot zhe klass,
esli v nih sovpadayut imena shablonov tipa i znacheniya ukazannyh
parametrov. Naprimer, v sleduyushchih opisaniyah x i y odnogo tipa,
kotoryj otlichen ot tipa z:

          template<class E, int size> class buffer;

           buffer<char, 2*512> x;
           buffer<char,1024> y;
           buffer<char,512> z;

Nizhe privedeny opisaniya, v kotoryh odinakovyj tip imeyut x2 i x3.
On otlichaetsya ot tipov x1 i x4:

           template<class T, void(*err_fct)()>
              class list { /* ... */ };

           list<int,&error_handler1> x1;
           list<int,&error_handler2> x2;
           list<int,&error_handler2> x3;
           list<char,&error_handler2> x4;



SHablon tipa dlya funkcii opredelyaet kak budet stroit'sya funkciya. Naprimer,
semejstvo funkcij sort mozhno opisat' sleduyushchim obrazom:

           template<class T> void sort(vector<T>);

SHablon tipa dlya funkcii porozhdaet neogranichennoe mnozhestvo peregruzhennyh
funkcij. Funkciya, porozhdaemaya shablonom tipa dlya funkcij, nazyvaetsya
shablonnoj funkciej. Ona ekvivalentna funkcii, v opisanii kotoroj ukazan
tip, sootvetstvuyushchij shablonu, sm. $$R.14.5.
   Pri vyzove shablonnoj funkcii parametry shablona tipa ne zadayutsya
yavno, vmesto etogo primenyaetsya pravilo razresheniya neopredelennosti
peregruzhennyh funkcij. Rassmotrim primer:

           vector<complex> cv(100);
           vector<int> ci(200);

           void f(vector<complex>& cv, vector<int>& ci)
           {
             sort(cv);   // vyzyvaetsya sort(vector<complex>)
             sort(ci);   // vyzyvaetsya sort(vector<int>)
           }

    SHablonnaya funkciya mozhet byt' peregruzhena kak obychnymi, tak i
shablonnymi funkciyami s tem zhe imenem. Dlya razresheniya neopredelennosti
shablonnyh i obychnyh funkcij s odnim i tem zhe imenem nado
posledovatel'no projti tri shaga:
   [1] Popytat'sya najti tochno sopostavimuyu vyzovu ($$R.13.2) funkciyu,
       i esli ona najdena, vyzvat' ee.
   [2] Popytat'sya najti shablon tipa dlya funkcij, po kotoromu
       mozhno sozdat' tochno sopostavimuyu s rassmatrivaemym vyzovom
       funkciyu. Esli udalos' najti, to vyzvat' funkciyu.
   [3] Popytat'sya primenit' obychnoe pravilo razresheniya neopredelennosti
       peregruzhennyh funkcij ($$R.13.2). Esli s ego pomoshch'yu
       funkciya najdena, vyzvat' ee.
Esli ne najdeno sopostavimoj funkcii, vyzov yavlyaetsya oshibochnym.
Esli uzhe na pervom shage najdeno bolee odnogo kandidata,
sopostavimogo s dannoj funkciej, to vyzov takzhe schitaetsya neodnoznachnym
i oshibochnym.
    Uspeshnoe vypolnenie shaga [2] privedet k sozdaniyu nekotoroj
shablonnoj funkcii s parametrami ($$R.14.5), tipy kotoryh tochno
sopostavyatsya s tipami parametrov, ukazannyh v vyzove. V etom sluchae
nedopustimo rashozhdenie dazhe za schet trivial'nyh preobrazovanij ($$R.13.2).
   Takie zhe dejstviya primenyayutsya dlya sopostavleniya tipov ukazatelej
na funkcii ($$R.13.3).
   Rassmotrim primer:

         template<class T> T max(T a, T b) { return a>b?a:b; };

         void f(int a, int b, char c, char d)
         {
           int m1 = max(a,b);   // max(int a, int b)
           char m2 = max(c,d);  // max(char c, char b)
           int m3 = max(a,c);   // oshibka: nel'zya sozdat' max(int,char)
         }

   Dobaviv k etomu primeru opisanie

         int max(int,int);

mozhno razreshit' neopredelennost' dlya tret'ego vyzova, poskol'ku teper'
zadana funkciya, kotoraya posle standartnogo preobrazovaniya char v int,
mozhet sopostavit'sya s vyzovom max(a,c).
   Opredelenie  shablona tipa dlya funkcii ispol'zuetsya dlya sozdaniya
razlichnyh variantov shablona tipa. Dlya vyzova opredelennogo varianta
dostatochno lish' opisaniya shablona tipa.
   Kazhdyj parametr-shablona-tipa, kotoryj priveden v
spiske-parametrov-shablona-tipa dolzhen obyazatel'no ispol'zovat'sya pri
zadanii tipov parametrov v shablone tipa dlya funkcii.

          template<class T> T* create(); //oshibka

          template<class T>
              void f() { // oshibka
                 T a;
                 // ...
              }

Vse parametry-shablona-tipa, privedennye v shablone tipa dlya funkcii,
dolzhny byt' parametrami-tipa.



Dlya kazhdogo imeni shablona tipa v programme dolzhno sushchestvovat' tol'ko
odno opredelenie. Opisanij mozhet byt' neskol'ko. Opredelenie
ispol'zuetsya dlya sozdaniya special'nyh shablonnyh klassov i shablonnyh
funkcij, kotorye budut sootvetstvovat' shablonu tipa.
    Konstrukciya imya-shablonnogo-klassa vvodit opisanie shablonnogo klassa.
    Vyzov shablonnoj funkcii ili vzyatie ee adresa vvodit opisanie
shablonnoj funkcii. Dlya vyzova ili vzyatiya adresa shablonnoj funkcii
v yazyke sushchestvuet osoboe soglashenie: imya shablonnoj funkcii
ispol'zuetsya tochno tak zhe kak imya obychnoj funkcii. Opisanie funkcii
s takim zhe imenem, kak u shablonnoj funkcii, i s sopostavimymi tipami
parametrov, vvodit opisanie special'noj shablonnoj funkcii.
    Esli dlya vypolneniya nekotoryh operacij trebuetsya opredelenie
special'nogo shablonnogo klassa ili special'noj shablonnoj funkcii,
i esli takogo opredeleniya v programme net, to ono budet sozdano.
    Opredelenie obychnoj (neshablonnoj) funkcii s tipom, kotoryj
tochno sopostavlyaetsya s tipom iz opisaniya shablonnoj funkcii,
schitaetsya opredeleniem special'noj shablonnoj funkcii. Rassmotrim
primer:

          template<class T> void sort(vector<T>& v) { /* ... */ }

          void sort(vector<char*>& v) { /* ... */ }

Zdes' opredelenie funkcii sort budet ispol'zovat'sya dlya toj funkcii
iz semejstva sort, kotoraya sopostavlyaetsya pri vyzove s tipom
parametra vector<char*>. Dlya drugih tipov vector budet sozdavat'sya
sootvetstvuyushchee im opredelenie funkcii po shablonu tipa.
   Mozhno opredelit' klass, kotoryj zadaet shablonnyj klass, naprimer:

          template<class T> class stream { /* ... */ };

         class stream<char> { /* ... */ };

Zdes' opisanie klassa budet ispol'zovat'sya v kachestve opredeleniya
potoka simvolov (stream<char>). Drugie potoki budut upravlyat'sya
s pomoshch'yu shablonnyh funkcij, sozdavaemyh po shablonu tipa dlya funkcij.
    Poka ne poyavitsya opisanie shablona tipa dlya klassa, nikakie operacii,
kotorym trebuetsya opredelennyj klass, ne mogut byt' proizvedeny nad
shablonnym klassom. Posle etogo special'nyj shablonnyj klass
budet schitat'sya opredelennym, prichem srazu zhe pered pervym global'nym
opisaniem, ispol'zuyushchim ego imya.



Funkciya-chlen shablonnogo klassa schitaetsya neyavnoj shablonnoj funkciej,
a parametry shablona tipa dlya ee klassa - ee shablonnymi parametrami.
Privedem primer, v kotorom opisany tri shablona tipa dlya funkcii:

         template<class T> class vector {
            T* v;
            int sz;
         public:
            vector(int);
            T& operator[](int);
            T& elem(int i) { return v[i]; }
            // ...
         };

Funkciyu, vypolnyayushchuyu indeksaciyu, mozhno opredelit' sleduyushchim obrazom:

         template<class T> T& vector<T>::operator[](int i)
         {
           if (i<0 || sz>=i) error("vector: range error");
           return v[i];
         }

    SHablonnyj parametr dlya vector<T>::operator[]() budet zadavat'sya
tem tipom vector, k kotoromu primenyaetsya operaciya indeksacii.

         vector<int> v1(20);
         vector<complex> v2(30);

         v1[3] = 7;            // vector<int>::operator[]()
         v2[3] = complex(7,8); // vector<complex>::operator[]()



Funkciya-drug dlya shablona tipa ne yavlyaetsya neyavnoj shablonnoj funkciej,
naprimer:

         template<class T> class task {
            // ...
            friend void next_time();
            friend task<T>* preempt(task<T>*);
            friend task* prmt(task*);  // oshibka
            // ...
         };

Zdes' funkciya next_time() stanovitsya drugom vseh klassov task, a
kazhdyj klass task imeet v kachestve druga funkciyu preempt() c
sootvetstvuyushchimi tipami parametrov. Funkciyu preempt() mozhno
opredelit' kak shablon tipa.

         template<class T>
            task<T>* preempt(task<T>* t) { /* ... */ }

     Opisanie funkcii prmt() yavlyaetsya oshibochnym, poskol'ku tipa
task ne sushchestvuet, a est' tol'ko special'nye shablonnye tipy
task<int>, task<record>, i t.d.



Dlya kazhdogo shablonnogo klassa ili funkcii, sozdavaemyh po shablonu
tipa, obrazuetsya svoya kopiya staticheskih peremennyh ili chlenov.
Rassmotrim primer:

          template<class T> class X {
             static T s;
             // ...
          };

          X<int> aa;
          X<char*> bb;

Zdes' v klasse X<int> est' staticheskij chlen tipa int, a v klasse
X<char> est' staticheskij chlen tipa char*.
   Analogichno, v privedennom nizhe primere, funkciya f(int*) imeet
staticheskij chlen s tipa int, a funkciya f(char**) imeet staticheskij
chlen tipa char**:

          template<class T> f(T* p)
          {
             static T s;
             // ...
          }

          void g(int a, char* b)
          {
             f(&a);
             f(&b);
          }





Pri obrabotke osobyh situacij v hode vypolneniya programmy informaciya i
upravlenie peredayutsya iz nekotoroj tochki obrabotchiku osobyh
situacij. Obrabotchik nahoditsya v cepochke vypolnennyh vyzovov
funkcij. Upravlenie obrabotchiku peredaetsya s pomoshch'yu
vyrazheniya-zapuska, kotoroe mozhet byt' tol'ko v proveryaemom-bloke
obrabotchika ili v funkcii, vyzvannoj iz proveryaemogo-bloka.

            proveryaemyj-blok:
                 try sostavnoj-operator spisok-obrabotchikov

            spisok-obrabotchikov:
                 obrabotchik spisok-obrabotchikov opt

            obrabotchik:
                 catch ( opisanie-osoboj-situacii ) sostavnoj-operator

            opisanie-osoboj-situacii:
                 spisok-specifikacij-tipa opisatel'
                 spisok-specifikacij-tipa abstraktnyj-opisatel'
                 spisok-specifikacij-tipa
                 ...

            vyrazhenie-zapuska:
                 throw vyrazhenie opt

Konstrukciya proveryaemyj-blok yavlyaetsya operatorom ($$R.6), a
vyrazhenie-zapuska - unarnym vyrazheniem tipa void ($$R.5). Inogda
vyrazhenie-zapuska nazyvayut "tochkoj zapuska", a pro funkciyu, v kotoroj
vstretilos' vyrazhenie-zapuska, govoryat, chto ona "zapuskaet osobuyu
situaciyu. CHast' programmy, kotoroj peredaetsya upravlenie iz tochki
zapuska nazyvaetsya obrabotchikom.



Pri zapuske osoboj situacii upravlenie peredaetsya obrabotchiku. Zapusk
soprovozhdaetsya peredachej ob容kt, tip kotorogo opredelyaet, kakoj
obrabotchik dolzhen perehvatit' osobuyu situaciyu. Tak, vyrazhenie

           throw "Help!";

mozhet byt' perehvacheno nekotorym obrabotchikom  s tipom char*:

           try {
             // ...
           }
           catch(const char* p) {
            // zdes' obrabatyvaetsya osobaya situaciya v simvol'nyh strokah
           }

a osobaya situaciya Overflow (perepolnenie):

           class Overflow {
             // ...
           public:
             Overflow(char,double,double);
           };

           void f(double x)
           {
             // ...
             throw Overflow('+',x,3.45e107);
           }

mozhet byt' perehvachena obrabotchikom

          try {
                // ...
                f(1.2);
                // ...
          }
          catch(Overflow& oo) {
                // zdes' obrabotka osoboj situacii tipa Overflow
          }

    Pri zapuske osoboj situacii upravlenie peredaetsya blizhajshemu
obrabotchiku sootvetstvuyushchego tipa. "Blizhajshij" - eto obrabotchik,
proveryaemyj-blok kotorogo poslednim poluchil upravlenie i ono eshche
ne bylo peredano ottuda. CHto takoe "sootvetstvuyushchij" tip
opredelyaetsya v $$R.15.4.
    Pri vypolnenii vyrazheniya-zapuska sozdaetsya vremennyj ob容kt
staticheskogo tipa, kotoryj sluzhit operandom v komande throw,
|tot ob容kt ispol'zuetsya dlya inicializacii peremennoj,
sootvetstvuyushchego tipa, opisannoj v obrabotchike. Esli ne schitat'
ogranichenij na sopostavlenie tipov (sm. $$R.15.4) i ispol'zovanie
 vremennoj peremennoj, to operand throw analogichen parametru funkcii
 pri vyzove ($$R.5.2.2) ili operandu v operatore return.
    Esli mozhno bylo by, ne menyaya smysla programmy za schet otkaza
ot vyzovov konstruktorov i destruktorov dlya vremennogo ob容kta
($$R.12.1), obojtis' sovsem bez vremennogo ob容kta, to osobuyu
situaciyu mozhno bylo by neposredstvenno inicializirovat' v obrabotchike
parametrom vyrazheniya zapuska.
    Esli v vyrazhenii-zapuska operand ne zadan, to proishodit
perezapusk obrabotki osoboj situacii. Takoe vyrazhenie-zapuska
mozhet poyavitsya tol'ko v samom obrabotchike ili v funkcii, kotoraya
neposredstvenno ili oposredovanno vyzyvaetsya iz nego.
Naprimer, fragment programmy, kotoryj vypolnyaetsya pri obrabotke osoboj
situacii, esli nel'zya eshche polnost'yu provesti etu obrabotku, mozhet
vyglyadet' tak:

        try {
          // ...
        }
        catch (...) { // perehvat vseh osobyh situacij
         //  (chastichnaya) obrabotka osobyh situacij
        throw; // peredacha ostal'nyh osobyh situacij drugomu obrabotchiku

      }



Kogda upravlenie peredaetsya iz tochki zapuska osoboj situacii
obrabotchiku, to vyzyvayutsya destruktory dlya vseh avtomaticheskih
ob容ktov, postroennyh s momenta vhoda v proveryaemyj-blok.
    Esli ob容kt ne byl postroen polnost'yu, to destruktory
vyzyvayutsya tol'ko dlya polnost'yu postroennyh vlozhennyh v nego ob容ktov.
Krome togo, esli osobaya situaciya zapuskaetsya v konstruktore pri
postroenii elementa avtomaticheskogo massiva, to unichtozhat'sya budut
tol'ko uzhe postroennye elementy etogo massiva.
   Process vyzova destruktorov dlya unichtozheniya avtomaticheskih
ob容ktov, postroennyh v hode vypolneniya programmy ot nachala
proveryaemogo-bloka do vyrazheniya-zapuska, nazyvaetsya "raskruchivaniem
steka".



Obrabotchik tipa T, const T, T& ili const& sopostavim s
vyrazheniem-zapuska, imeyushchim operand tipa E, esli:
   [1] T i E yavlyayutsya odnim tipom;
   [2] T yavlyaetsya dostupnym ($$R.4.6) bazovym klassom E v tochke
       zapuska;
   [3] T yavlyaetsya tipom ukazatelya, a E yavlyaetsya takim tipom ukazatelya,
       kotoryj mozhno v tochke zapuska preobrazovat' v T s pomoshch'yu
       standartnyh preobrazovanij ukazatelya ($$R.4.6).
   Rassmotrim primer:

         class Matherr { /* ... */ virtual vf(); };
         class Overflow : public Matherr { /* ... */ };
         class Underflow : public Matherr { /* ... */ };
         class Zerodivide : public Matherr { /* ... */ };

         void f()
         {
           try {
              g();
           }

          catch (Overflow oo) {
            // ...
          }
          catch (Matherr mm) {
           // ...
          }
        }

Zdes' obrabotchik Overflow budet perehvatyvat' situacii tipa
Overflow, a obrabotchik Matherr budet perehvatyvat' situacii tipa
Matherr i vseh tipov, yavlyayushchihsya obshchimi proizvodnymi ot Matherr,
vklyuchaya Underflow i Zerodivide.
   Obrabotchiki v proveryaemom-bloke podbirayutsya dlya dannoj osoboj
situacii v poryadke ih opisaniya. Schitaetsya oshibkoj , esli obrabotchik
dlya bazovogo klassa pomeshchen pered obrabotchikom dlya proizvodnogo klassa,
poskol'ku pri takom raspolozhenii upravlenie nikogda ne popadet
k obrabotchiku dlya proizvodnogo klassa.
   |llipsis ... v opisanii-osoboj-situacii dejstvuet tak zhe kak, i
v opisanii parametrov funkcii, on sopostavim s lyuboj osoboj
situaciej. Esli zadan ellipsis, to ispol'zuyushchij ego obrabotchik
dolzhen idti poslednim v proveryaemom-bloke.
   Esli v proveryaemom-bloke ne proizoshlo sopostavleniya ni s odnim
iz obrabotchikov, poisk sootvetstvuyushchego obrabotchika prodolzhaetsya
v dinamicheski ob容mlyushchem proveryaemom-bloke. Esli vo vsej programme
ne proizoshlo sopostavleniya ni s odnim obrabotchikom, vyzyvaetsya
funkciya terminate() ($$R.15.7).
   Osobaya situaciya schitaetsya obrabotannoj posle vhoda v telo
obrabotchika. V etot moment zavershitsya "raskruchivanie steka".



Vozniknovenie i perehvatyvanie osoboj situacii vliyaet na
vzaimodejstvie funkcij. Spisok osobyh situacij, kotorye pryamo ili
kosvenno mozhet zapustit' dannaya funkciya, mozhno zadat' kak chast' ee
opisaniya. Konstrukciya specifikaciya-osoboj-situacii
predshestvuet opisatelyu funkcii.

         specifikaciya-osoboj-situacii:
              throw ( spisok-tipov opt )

         spisok-tipov:
              imya-tipa
              spisok-tipov , imya-tipa

Privedem primer:

         void f() throw (X,Y)
         {
           // ...
         }

  Esli funkciya poprobuet zapustit' neukazannuyu v spiske situaciyu,
upravlenie peredaetsya funkcii unexpected(), sm. $$R.15.8.
  Realizaciya yazyka ne dolzhna zapreshchat' vyrazhenie tol'ko potomu,
chto pri ego vychislenii vozmozhen zapusk osoboj situacii, ne ukazannoj
v specifikacii-osoboj situacii opisaniya funkcii. Obrabotka nepredvidennyh
osobyh situacij proishodit v dinamike.
  Funkciya, v kotoroj otsutstvuet specifikaciya-osoboj-situacii,
mozhet zapustit' lyubuyu osobuyu situaciyu.
  Funkciya s pustoj specifikaciej-osobyh-situacij (throw()) ne dolzhna
zapuskat' nikakih osobyh situacij.
  Esli funkciya mozhet zapustit' osobuyu situaciyu klassa X,  to ona
mozhet zapustit' osobuyu situaciyu lyubogo klassa, yavlyayushchegosya obshchim
proizvodnym klassom ot X.
  Konstrukciya specifikaciya-osoboj-situacii ne otnositsya k tipu
funkcii.



Mehanizm upravleniya osobymi situaciyami ispol'zuet dlya reakcii na oshibki
pri samoj obrabotke osobyh situacij funkcii:

terminate() i unexpected().



Inogda ot predusmotrennoj obrabotki osobyh situacij prihoditsya
perehodit' k bolee grubym priemam, naprimer:
  - kogda mehanizm upravleniya osobymi situaciyami ne smog najti
    obrabotchik dlya zapushchennoj osoboj situacii;
  - kogda mehanizm upravleniya osobymi situaciyami stolknulsya
    s narushennoj strukturoj steka;
  - kogda destruktor, vyzvannyj v processe raskrutki steka pri zapuske
    osoboj situacii, sam pytaetsya zavershit' vypolnenie programmy,
    zapustiv osobuyu situaciyu.
V etih sluchayah vyzyvaetsya funkciya

    void terminate();

Ona v svoyu ochered' vyzyvaet funkciyu, kotoraya byla ukazana kak parametr
pri poslednem obrashchenii k set_terminate():

    typedef void(*PFV)();
    PFV set_terminate(PFV);

Funkciya, kotoraya byla zadana v predydushchem vyzove set_terminate(),
budet vozvrashchaemym znacheniem tekushchego vyzova. |to pomogaet
pol'zovatelyu realizovat' algoritm vosstanovleniya steka. Po umolchaniyu
funkciya terminate() vyzyvaet abort().
   Vybor s pomoshch'yu terminate() takoj funkcii, kotoraya vmesto
dejstvitel'nogo zaversheniya programmy, pytaetsya vernut'sya v
vyzvavshuyu programmu, yavlyaetsya oshibkoj.



Esli funkciya, imeyushchaya specifikaciyu-osoboj-situacii, zapuskaet
neukazannuyu osobuyu situaciyu, to vyzyvaetsya funkciya

      void unexpected();

Ona v svoyu ochered' vyzyvaet funkciyu, kotoraya byla zadana kak
parametr pri poslednem obrashchenii k set_unexpected():

      typedef void(*PFV)();
      PFV set_unexpected(PFV);

Funkciya, kotoraya byla zadana v predydushchem vyzove set_unexpected(),
budet vozvrashchaemym znacheniem tekushchego vyzova. |to pomogaet
pol'zovatelyu realizovat' algoritm vosstanovleniya steka. Po umolchaniyu
unexpected() vyzyvaet terminate(). Poskol'ku po umolchaniyu
terminate() vyzyvaet abort(), rezul'tatom budet neposredstvennoe
i tochnoe obnaruzhenie oshibki.



  Dlya formal'nogo parametra operacii catch dejstvuyut takie zhe
pravila dostupa, kak i dlya formal'nogo parametra funkcii, v kotoroj
zadana operaciya catch.
  Pri zapuske osoboj situacii mozhno ukazyvat' takoj ob容kt, kotoryj
mozhno kopirovat' i unichtozhat' v oblasti vidimosti funkcii, gde
zadana operaciya throw.




Realizaciya yazyka S++ vklyuchaet preprocessor s vozmozhnostyami
makropodstanovki, uslovnoj translyacii i vklyucheniya ukazannyh
fajlov.
   Dlya peredachi zadanij preprocessoru sluzhat stroki, nachinayushchiesya
s simvola # (pered nim mogut idti probely i simvoly gorizontal'noj
tabulyacii). Takie stroki nazyvayutsya komandami, i ih sintaksis
opredelyaetsya nezavisimo ot ostal'nogo yazyka. Komandy mogut
nahodit'sya v lyubom meste programmy, i ih dejstvie prodolzhaetsya
(nezavisimo ot pravil oblastej vidimosti S++) do konca dannoj
edinicy translyacii ($$R.2).
   Komandu preprocessora, kak i lyubuyu stroku, mozhno prodolzhit' na
sleduyushchej stroke vhodnogo teksta, pomestiv simvol obratnoj
drobnoj cherty neposredstvenno pered simvolom konca prodolzhaemoj
stroki. Preprocessor do togo, kak vhodnaya stroka budet razbita na
leksemy, udalyaet simvoly obratnoj drobnoj cherty i konca stroki.
Simvol obratnoj drobnoj cherty ne dolzhen byt' poslednim simvolom
vhodnogo fajla.
   K leksemam preprocessora otnosyatsya: leksemy samogo yazyka ($$R.2.1),
imya fajla, kotoroe ispol'zuetsya v komande #include i voobshche lyuboj
simvol, otlichnyj ot obobshchennogo probela i nesovpadayushchij ni s kakoj
iz leksem preprocessora.



Po opredeleniyu sushchestvuet neskol'ko faz preprocessornoj obrabotki.
V konkretnoj realizacii fazy mogut slivat'sya, no rezul'tat vse ravno
dolzhen byt' takim, kak budto byli vypolneny vse fazy.
  Perechislim ih.

  Pri neobhodimosti simvoly, zavisyashchie ot sistemy simvoly, oboznachayushchie
konec stroki, zamenyayutsya na standartnyj simvol konca stroki. Analogichnoj
zamene podlezhat vse zavisyashchie ot sistemy simvoly. Opredelennye
posledovatel'nosti simvolov (trigrafy) zamenyayutsya na ekvivalentnyj
im otdel'nyj simvol ($$R.16.2).

  Udalyayutsya vse takie pary simvolov: obratnaya drobnaya cherta, sleduyushchij
za nej simvol konca stroki. V rezul'tate budut slity stroki vhodnogo
teksta, iz kotoryh byla udalena eta para.

  Vhodnoj tekst razbivaetsya na leksemy preprocessora i posledovatel'nost'
obobshchennyh probelov. Kazhdyj kommentarij zamenyaetsya na odin probel.
Vhodnoj tekst ne dolzhen konchat'sya posredi leksemy ili kommentariya.

  Vypolnyayutsya komandy preprocessora, i proizvodyatsya makropodstanovki
($$R.16.3, $$R.16.4, $$R.16.5, $$R.16.6, $$R.16.7 i $$R.16.8).

  V simvol'nyh konstantah i strokah literalov kombinacii special'nyh
simvolov zamenyayutsya na svoi ekvivalenty ($$R.2.5.2).

 Slivayutsya sosednie stroki literalov.

 Rezul'tat preprocessornoj obrabotki podvergaetsya sintaksicheskomu
i semanticheskomu analizu, transliruetsya, a zatem svyazyvaetsya s
neobhodimymi bibliotekami i drugimi programmami.



Prezhde chem nachnetsya kakaya-libo inaya preprocessornaya obrabotka,
kazhdoe vhozhdenie trigrafnoj posledovatel'nosti zamenyaetsya na odin
simvol v sootvetstvii s privedennoj nizhe tablicej.

          ??=  #        ??(  [
          ??/  \        ??)  [
          ??'  ^        ??!  |

Naprimer, stroka

      ??=define arraycheck(a,b)  a??(b??) ??!??! b??(a??)

preobrazuetsya v

      #define arraycheck(a,b) a[b] || b[a]



Komanda vida

     #define identifikator stroka-leksem

nazyvaetsya makroopredeleniem. Ona ukazyvaet preprocessoru, chto nado
proizvesti zamenu vseh posleduyushchih vhozhdenij identifikatora na zadannuyu
posledovatel'nost' leksem, nazyvaemuyu strokoj zameny. Obobshchennye
probely, okruzhayushchie etu posledovatel'nost' leksem, otbrasyvayutsya.
Naprimer, pri opredelenii

      #define SIDE 8

opisanie

      char chessboard[side][side];

posle makropodstanovki primet vid

      char chessboard[8][8];

Opredelennyj takim sposobom identifikator mozhno pereopredelit'
s pomoshch'yu drugoj komandy #define, no pri uslovii, chto stroki
zameny v oboih opredeleniyah sovpadayut. Vse simvoly obobshchennogo
probela, razdelyayushchie leksemy, schitayutsya identichnymi.
   Komanda vida
identifikator ( identifikator, ... ,identifikator) stroka-leksem
nazyvaetsya makroopredeleniem s parametrami ili "funkcional'nym"
makroopredeleniem. V nem nedopustimy probely mezhdu pervym
identifikatorom i simvolom (. Opredelennyj takim sposobom
identifikator mozhno pereopredelit' s pomoshch'yu drugogo funkcional'nogo
makroopredeleniya, no pri uslovii, chto vo vtorom opredelenii
to zhe chislo i te zhe naimenovaniya parametrov, chto i v pervom, a obe
stroki zameny sovpadayut. Vse simvoly obobshchennogo probela, razdelyayushchie
leksemy, schitayutsya identichnymi.
   Posleduyushchie vhozhdeniya identifikatora, opredelennogo v
funkcional'nom makroopredelenii, esli za nim sleduyut simvol
(, posledovatel'nost' leksem, razdelennyh zapyatymi, i simvol
), zamenyayutsya na stroku leksem iz makroopredeleniya. Obobshchennye
probely, okruzhayushchie stroku zameny, otbrasyvayutsya. Kazhdoe vhozhdenie
identifikatora, iz spiska parametrov makroopredeleniya, zamenyaetsya
na posledovatel'nost' leksem, predstavlyayushchuyu sootvetstvuyushchij
fakticheskij parametr v makrovyzove. Fakticheskimi parametrami yavlyayutsya
stroki leksem, razdelennye zapyatymi. Zapyataya, vzyataya v kavychki, ili
nahodyashchayasya v simvol'noj konstante ili vo vlozhennyh kruglyh skobkah,
ne razdelyaet parametrov. CHislo fakticheskih parametrov makrovyzova dolzhno
sovpadat' s chislom parametrov makroopredeleniya.
   Posle identifikacii parametrov dlya funkcional'nogo makroopredeleniya
proishodit podstanovka fakticheskih parametrov. Posle vypolneniya podstanovok
v parametre (esli oni byli) etot parametr v stroke zameny zameshchaetsya
fakticheskim parametrom iz makrovyzova ($$R.16.3.3); isklyucheniya
sostavlyayut sluchai, kogda parametru predshestvuet leksema # ($$R.16.3.1),
ili s nim sosedstvuet leksema ## ($$R.16.3.2).
    Privedem primer. Pust' est' makroopredeleniya

       #define index_mask 0XFF00
       #define extract(word,mask)   word & mask

Togda makrovyzov

       index = extract(packed_data,index_mask);

posle podstanovki primet vid

       index = packed_data & 0XFF00;

   Dlya oboih vidov makroopredelenij stroka zameny proveryaetsya  na
nalichie drugih makroopredelenij ($$R.16.3.3).



Esli neposredstvenno pered parametrom v stroke zameny idet leksema
#, to pri podstanovke parametr i operaciya # budut zameneny
na stroku literalov , soderzhashchuyu imya sootvetstvuyushchego parametra
makrovyzova. V simvol'noj konstante ili stroke literalov, vhodyashchih
v parametr, pered kazhdym vhozhdeniem \ ili " vstavlyaetsya simvol \.
     Naprimer, esli est' makroopredeleniya

        #define path(logid,cmd) "/usr/" #logid "/bin/" #cmd

to makrovyzov

        char* mytool=path(joe,readmail);

privedet k takomu rezul'tatu:

        char* mytool="/usr/" "joe" "/bin/" "readmail";

Posle konkatenacii sosednih strok ($$R.16.1) poluchim:

        char* mytool="/usr/joe/bin/readmail";



Esli v stroke zameny mezhdu dvumya leksemami, odna iz kotoryh
predstavlyaet parametr makroopredeleniya, poyavlyaetsya operaciya
##, to sama operaciya ## i okruzhayushchie ee obobshchennye probely
udalyayutsya. Takim obrazom, rezul'tat operacii ## sostoit v
konkatenacii.
   Pust' est' makroopredelenie,

        #define inherit(basenum) public Pubbase ## basenum, \
                                 private Privbase ## basenum

togda makrovyzov

        class D : inherit(1) { };

privedet k takomu rezul'tatu:

        class D : public Pubbase1, Privbase1 { };

   Makroopredelenie, kotoroe v stroke zameny sosedstvuet s
##, ne podlezhit podstanovke, odnako, rezul'tat konkatenacii mozhet
ispol'zovat'sya dlya podstanovki. Privedem primer. Pust' est'
opredeleniya:

        #define concat(a)    a ## ball
        #define base         B
        #define baseball     sport

Togda makrovyzov

        concat(base)

dast v rezul'tate

        sport

a vovse ne

        Bball



Posle togo, kak v stroke zameny proizoshla podstanovka vseh parametrov
makrovyzova, poluchivshayasya stroka prosmatrivaetsya povtorno dlya
obnaruzheniya dopolnitel'nyh makroopredelenij. Esli v processe
povtornyh prosmotrov stroki zameny najdeno imya makroopredeleniya, to
podstanovka vse zhe ne proishodit.
    Rekursivnuyu podstanovku nel'zya vypolnit' kak komandu
preprocessora, hotya ona kazhetsya dlya nego estestvennoj komandoj.



Posle poyavleniya makroopredeleniya identifikator iz nego schitaetsya
opredelennym i ostaetsya v tekushchej oblasti vidimosti (nezavisimo ot
pravil oblastej vidimosti v S++) do konca edinicy translyacii ili
poka ego opredelenie ne budet otmeneno s pomoshch'yu komandy #undef.
   Komanda #undef imeet vid:

        #undef identifikator

Ona zastavlyaet preprocessor "zabyt'" makroopredelenie s etim
identifikatorom. Esli ukazannyj identifikator ne yavlyaetsya
opredelennym v dannyj moment makroimenem, to komanda #undef
ignoriruetsya.



Upravlyayushchaya stroka vida:

        #include <imyafajla>

privodit k zamene dannoj stroki na soderzhimoe fajla s ukazannym imenem.
Poisk ukazannogo fajla prohodit v opredelennoj posledovatel'nosti
chastej arhiva sistemy i opredelyaetsya realizaciej.
    Analogichno, upravlyayushchaya stroka vida:

        #include "imyafajla"

privodit k zamene dannoj stroki na soderzhimoe fajla s ukazannym
imenem. Poisk etogo fajla nachinaetsya v osobyh (sistemnyh) chastyah
arhiva, ukazannyh v nachale posledovatel'nosti poiska. Esli tam on
ne najden, to poisk fajla idet po vsej posledovatel'nosti, kak esli by
upravlyayushchaya stroka imela vid:

        #include <imyafajla>

   V imeni fajla, ogranichennom simvolami < i > nel'zya ispol'zovat'
simvoly konca stroki ili >. Esli v takom imeni poyavitsya odin iz
simvolov ', \, ili ", a takzhe posledovatel'nost' simvolov /* ili //,
to rezul'tat schitaetsya neopredelennym.
   V imeni fajla, ogranichennom paroj simvolov " nel'zya ispol'zovat'
simvoly konca stroki ili ", hotya simvol > dopustim. Esli v takom
imeni poyavitsya simvol ' ili \ ili posledovatel'nost' /* ili //,
to rezul'tat schitaetsya neopredelennym.
   Esli komanda

       #include stroka-leksem

imeet vid, sootvetstvuyushchij ni pervoj, ni vtoroj upravlyayushchej stroke,
to leksemy preprocessora, zadannye v etoj komande obrabatyvayutsya kak
obychnyj tekst. V rezul'tate dolzhna poluchit'sya komanda, vid kotoroj
sootvetstvuet odnomu iz privedennyh. Ona i budet vypolnena kak polozheno.
  Komanda #include mozhet byt' v fajle, kotoryj sam poyavilsya v
rezul'tate vypolneniya drugoj komandy #include.
  Realizaciya mozhet nakladyvat' ogranichenie na glubinu vlozhennosti
komandy #include vo vhodnyh fajlah programmy, kotorye prihoditsya
chitat' dlya vypolneniya pervonachal'noj komandy #include v odnom iz
vhodnyh fajlov.



S pomoshch'yu preprocessora mozhno organizovat' uslovnuyu translyaciyu
programmy. Sintaksicheski eto zadaetsya sleduyushchim obrazom:

         uslovnoe:
               chast'-if chasti-elif opt chast'-else opt stroka-endif

         chast'-if:
               stroka-if tekst

         stroka-if:
               # if vyrazhenie-konstanta
               # ifdef identifikator
               # ifndef identifikator

         chasti-elif:
               stroka-elif tekst
               chasti-elif stroka-elif tekst

         stroka-elif:
               # elif vyrazhenie-konstanta

         chast'-else:
               stroka-else tekst

         stroka-else:
               # else

         stroka-endif:
               # endif

    Konstantnye vyrazheniya v #if i #elif (esli eti chasti est')
vychislyayutsya v poryadke ih zadaniya v tekste do teh por, poka odno
iz nih ne okazhetsya otlichnym ot nulya. Operatory S++, sleduyushchie za
strokoj, v kotoroj vyrazhenie okazalos' ravnym nulyu, ne transliruyutsya.
Komandy preprocessora, idushchie za etoj strokoj ignoriruyutsya.
Posle togo, kak najdena komanda s nenulevym znacheniem vyrazheniya,
tekst vseh posleduyushchih chastej #elif i #else (t.e. operatory S++ i
komandy preprocessora) ignoriruetsya. Tekst, otnosyashchijsya k pervoj
komande s nenulevym znacheniem vyrazheniya podlezhit obychnoj preprocessornoj
obrabotke i translyacii. Esli znacheniya vseh vyrazhenij, ukazannyh v #if
i #elif, okazalis' ravnymi nulyu, togda obychnoj obrabotke podlezhit tekst,
otnosyashchijsya k #else.
    V vyrazhenii-konstante, kotoroe vstretilos' v #if ili #elif
mozhno ispol'zovat' unarnuyu operaciyu defined, prichem v dvuh
variantah:

            defined identifikator

ili

            defined (identifikator)

Esli eta operaciya primenyaetsya k identifikatoru, kotoryj byl opredelen
s pomoshch'yu komandy #define, i esli eto opredelenie ne bylo otmeneno
komandoj #undef, to rezul'tat raven 1, inache rezul'tat raven 0.
Sam identifikator defined nel'zya pereopredelit', nel'zya i otmenit'
ego opredelenie.
    Posle primeneniya operacij defined proishodit raskrytie vseh
vseh makroopredelenij, imeyushchihsya v konstantnom vyrazhenii
sm. $$R.16.3. V rezul'tate dolzhno poluchit'sya celochislennoe
vyrazhenie-konstanta, otlichayushcheesya ot opredeleniya v $$R.5.19 tem,
chto tipy int i unsigned int rassmatrivayutsya kak long i unsigned long
sootvetstvenno, a krome togo v etom vyrazhenii ne dolzhno byt'
operacij privedeniya, sizeof ili elementa perechisleniya.
    Upravlyayushchaya stroka

       #ifdef identifikator

ekvivalentna stroke

       #if defined identifikator

a upravlyayushchaya stroka

       #ifndef identifikator

ekvivalentna stroke

       #if !defined identifikator

   Konstrukcii, zadayushchie uslovnuyu translyaciyu, mogut byt' vlozhennymi,
no realizaciya mozhet nakladyvat' ogranichenie na glubinu vlozhennosti
etih konstrukcij.



Dlya udobstva napisaniya programm, porozhdayushchih tekst na S++, vvedena
upravlyayushchaya stroka vida:

       #line konstanta "imyafajla" opt

Ona zadaet znachenie predopredelennomu makroimeni __LINE__ ($$R.16.10),
kotoroe ispol'zuetsya v diagnosticheskih soobshcheniyah ili pri
simvolicheskoj otladke; a imenno: nomer sleduyushchej stroki
vhodnogo teksta schitaetsya ravnym zadannoj konstante, kotoraya dolzhna
byt' desyatichnym celym chislom. Esli zadano "imyafajla", to znachenie
makroimeni __FILE__ ($$R.16.10) stanovitsya ravnym imeni ukazannogo
fajla. Esli ono ne zadano, __FILE__ ne menyaet svoego znacheniya.
   Makroopredeleniya v etoj upravlyayushchej stroke raskryvayutsya do
vypolneniya samoj komandy.



Stroka vida:

       #error stroka-leksem

zastavlyaet realizaciyu vydat' diagnosticheskoe soobshchenie, sostoyashchee
iz zadannoj posledovatel'nosti leksem preprocessora.



Stroka vida:

       #pragma stroka-leksem

zastavlyaet realizaciyu vesti sebya nekotorym opredelennym obrazom
pri uslovii chto realizaciya  "ponimaet" etu stroku. Lyubaya
neraspoznannaya stroka #pragma ignoriruetsya.



Komanda preprocessora vida

       #

ne okazyvaet nikakogo dejstviya.



V processe translyacii opredelennuyu informaciyu soderzhat sleduyushchie
predopredelennye makroimena.

 __LINE__ desyatichnaya konstanta, soderzhashchaya nomer tekushchej stroki
          teksta programmy na S++.
 __FILE__ stroka literalov, predstavlyayushchaya imya transliruemogo
          vhodnogo fajla.
 __DATE__ stroka literalov, predstavlyayushchaya datu translyacii v vide
          "Mmm dd yyyy" ili "Mmm d yyyy", esli chislo men'she 10,
          (zdes' Mmm zadaet mesyac, dd - den', a yyyy - god).
 __TIME__ stroka literalov, predstavlyayushchaya vremya translyacii v vide
          "hh:mm:ss", (zdes' hh zadaet chasy, mm - minuty, a
          ss - sekundy).

Krome togo, schitaetsya opredelennym pri translyacii programmy na S++
makroimya __cplusplus.
Perechislennye makroimena nel'zya kak pereopredelyat', tak i otmenyat' ih
opredeleniya.
Makroimena __LINE__ i __FILE__ mozhno opredelit' s pomoshch'yu komandy
#line ($$R.16.6).
Opredeleno li makroimya __STDC, i esli da, to kakovo ego znachenie,
zavisit ot realizacii.



|to prilozhenie ne otnositsya k spravochnomu rukovodstvu yazyka i
ne yavlyaetsya opredeleniem konstrukcij C++.
   Ona tol'ko dolzhno sluzhit' bolee polnomu ponimaniyu S++. Nel'zya
rassmatrivat' ego kak tochnoe opredelenie yazyka, tak kak opisannaya zdes'
grammatika dopuskaet proizvol'noe mnozhestvo konstrukcij, kazhdaya iz
kotoryh zakonna dlya S++. CHtoby razlichat' vyrazheniya i opisaniya,
sleduet primenyat' pravila razresheniya neopredelennosti ($$r.6.8,
$$R.7.1, $$R.10.1.1). Dalee, dlya otseivaniya sintaksicheski pravil'nyh,
no bessmyslennyh, konstrukcij sleduet primenyat' pravila kontrolya
dostupa, razresheniya neopredelennosti i kontrolya tipa.



V opisaniyah: typedef ($$R.7.1.3), klassa ($$R.9), perechisleniya
($$R.7.2),  shablona tipa - ($$R.14) vvedeny novye, zavisyashchie ot
konteksta, sluzhebnye slova, a imenno:

        imya-klassa:
             identifikator

        imya-perechisleniya:
             identifikator

        imya-typedef:
             identifikator

Otmetim, chto imya-typedef, oboznachayushchee klass, yavlyaetsya v to zhe
vremya konstrukciej imya-klassa ($$R.9.1).



       vyrazhenie:
            vyrazhenie-prisvaivaniya
            vyrazhenie, vyrazhenie-prisvaivaniya

       vyrazhenie-prisvaivaniya:
         vyrazhenie-usloviya
         unarnoe-vyrazhenie operaciya-prisvaivaniya vyrazhenie-prisvaivaniya
         operaciya-prisvaivaniya: odin iz
              =  *=  /=  %=  +=  -=  >>=  <<=  &=  ^=  |=
       vyrazhenie-usloviya:
             logicheskoe-vyrazhenie-ILI
             logicheskoe-vyrazhenie-ILI ? vyrazhenie : vyrazhenie-usloviya

        logicheskoe-vyrazhenie-ILI:
             logicheskoe-vyrazhenie-I
             logicheskoe-vyrazhenie-ILI || logicheskoe-vyrazhenie-I

        logicheskoe-vyrazhenie-I:
             vyrazhenie-ILI
             logicheskoe-vyrazhenie-I && vyrazhenie-ILI

        vyrazhenie-ILI:
             vyrazhenie-isklyuchayushchego-ILI
             vyrazhenie-ILI | vyrazhenie-isklyuchayushchego-ILI

          vyrazhenie-isklyuchayushchego-ILI:
               vyrazhenie-I
               vyrazhenie-isklyuchayushchego-ILI ^ vyrazhenie-I

          vyrazhenie-I:
               vyrazhenie-ravenstva
               vyrazhenie-I & vyrazhenie-ravenstva

          vyrazhenie-ravenstva:
               vyrazhenie-otnosheniya
               vyrazhenie-ravenstva == vyrazhenie-otnosheniya
               vyrazhenie-ravenstva != vyrazhenie-otnosheniya

          vyrazhenie-otnosheniya:
               sdvigovoe-vyrazhenie
               vyrazhenie-otnosheniya <  sdvigovoe-vyrazhenie
               vyrazhenie-otnosheniya >  sdvigovoe-vyrazhenie
               vyrazhenie-otnosheniya <= sdvigovoe-vyrazhenie
               vyrazhenie-otnosheniya >= sdvigovoe-vyrazhenie

           sdvigovoe-vyrazhenie:
               additivnoe-vyrazhenie
               sdvigovoe-vyrazhenie << additivnoe vyrazhenie
               sdvigovoe-vyrazhenie >> additivnoe vyrazhenie

           additivnoe-vyrazhenie:
               mul'tiplikativnoe-vyrazhenie
               additivnoe vyrazhenie + mul'tiplikativnoe-vyrazhenie
               additivnoe-vyrazhenie - mul'tiplikativnoe-vyrazhenie

           mul'tiplikativnoe-vyrazhenie:
               vyrazhenie-pm
               mul'tiplikativnoe-vyrazhenie * vyrazhenie-pm
               mul'tiplikativnoe-vyrazhenie / vyrazhenie-pm
               mul'tiplikativnoe-vyrazhenie % vyrazhenie-pm

           vyrazhenie-pm:
               vyrazhenie-privedeniya
               vyrazhenie-pm .*  vyrazhenie-privedeniya
               vyrazhenie-pm ->* vyrazhenie-privedeniya

           vyrazhenie-privedeniya:
               unarnoe-vyrazhenie
               ( imya-tipa ) vyrazhenie-privedeniya

           unarnoe-vyrazhenie:
                postfiksnoe-vyrazhenie
                ++ unarnoe vyrazhenie
                -- unarnoe vyrazhenie
                unarnaya-operaciya vyrazhenie-privedeniya
                sizeof unarnaya-operaciya
                sizeof ( imya-tipa )
                vyrazhenie-razmeshcheniya
                vyrazhenie-osvobozhdeniya

          unarnaya-operaciya: odin iz
                *  &  +  -  !  ~

           vyrazhenie-razmeshcheniya:
               ::opt new parametry-new opt imya-tipa-new inicializator-new
               ::opt new parametry-new opt ( imya-tipa ) inicializator-new

          parametry-new:
                ( spisok-vyrazhenij )

          imya-tipa-new:
               spisok-specifikacij-tipa opisatel'-new opt

          opisatel'-new:
               * spisok-specifikacij-cv opt opisatel'-new opt
               imya-klassa :: spisok-specifikacij-cv opt opisatel'-new opt
               opisatel'-new opt [ vyrazhenie ]

          inicializator-new:
                ( spisok-inicializatorov opt )

          vyrazhenie-osvobozhdeniya:
                ::opt delete vyrazhenie-privedeniya
                ::opt delete [] vyrazhenie-privedeniya

          postfiksnoe-vyrazhenie:
                pervichnoe-vyrazhenie
                postfiksnoe-vyrazhenie [ vyrazhenie ]
                postfiksnoe-vyrazhenie ( spisok-vyrazhenij opt )
                imya-prostogo-tipa     ( spisok-vyrazhenij opt )
                postfiksnoe-vyrazhenie .  imya
                postfiksnoe-vyrazhenie -> imya
                postfiksnoe-vyrazhenie ++
                postfiksnoe-vyrazhenie --

          spisok-vyrazhenij:
                vyrazhenie-prisvaivaniya
                spisok-vyrazhenij , vyrazhenie-prisvaivaniya

         pervichnoe-vyrazhenie:
                literal
                this
                :: identifikator
                :: imya-funkcii-operacii
                :: utochnennoe-imya
                ( vyrazhenie )
                imya

          imya:
               identifikator
               imya-funkcii-operacii
               imya-funkcii-preobrazovaniya
               ~imya-klassa
               utochnennoe-imya

          utochnennoe-imya:
               utochnyayushchee-imya-klassa :: imya

          literal:
              celaya konstanta
              simvol'naya konstanta
              konstanta s plavayushchej tochkoj
              stroka literalov



       opisaniya:
              specifikacii-opisaniya opt spisok-opisatelej opt ;
              opisanie-asm
              opredelenie-funkcii
              specifikaciya-svyazi

        specifikaciya-opisaniya:
             specifikaciya-klassa-pamyati
             specifikaciya-tipa
             specifikaciya-fct
             specifikaciya-shablona-tipa
             friend
             typedef

        specifikacii-opisaniya:
             specifikacii-opisaniya opt specifikaciya-opisaniya

      specifikaciya-klassa-pamyati:
             auto
             register
             static
             extern

      specifikaciya-fct:
            inline
            virtual

     specifikaciya-tipa:
           imya-prostogo-tipa
           specifikaciya-klassa
           specifikaciya-perechisleniya
           specifikaciya-slozhnogo-tipa
           :: imya-klassa
           const
           volatile

     imya-prostogo-tipa:
           polnoe-imya-klassa
           utochnennoe-imya-tipa
           char
           short
           int
           long
           signed
           unsigned
           float
           double
           void

     specifikaciya-slozhnogo-tipa:
           sluzhebnoe-slovo-klassa imya-klassa
           sluzhebnoe-slovo-klassa identifikator

     sluzhebnoe-slovo-klassa:
           class
           struct
           union

     utochnennoe-imya-tipa:
           imya-typedef
           imya-klassa :: utochnennoe-imya-tipa

     polnoe-imya-klassa:
           utochnennoe-imya-klassa
           :: utochnennoe-imya-klassa

     utochnennoe-imya-klassa:
           imya-klassa
           imya-klassa :: utochnennoe-imya-klassa

      imya-perechisleniya:
           identifikator

      specifikaciya-perechisleniya:
          enum identifikator opt { spisok-perechisleniya }

      spisok-perechisleniya:
          element-perechisleniya
          spisok-perechisleniya , element-perechisleniya

      element-perechisleniya:
          identifikator
          identifikator = vyrazhenie-konstanta

     specifikaciya-svyazi:
         extern stroka-literal { spisok-opisanij opt }
         extern stroka-literal opisanie

     spisok-opisanij:
         opisanie
         spisok-opisanij opisanie

      opisanie-asm:
          asm ( stroka-literal) ;



      spisok-opisanij:
           opisatel'-s-inicializatorom
           spisok-opisanij , opisatel'-s-inicializatorom

      opisatel'-s-inicializatorom:
           opisatel' inicializator opt

      opisatel':
          imya-v-opisatele
          operaciya-ptr opisatel'
          opisatel' (spisok-opisanij-parametrov) spisok-specifikacij-cv opt
          opisatel' [ vyrazhenie-konstanta opt]
          ( opisatel' )

   operaciya-ptr:
         * spisok-specifikacij-cv opt
         & spisok-specifikacij-cv opt
         polnoe-imya-klassa :: * spisok-specifikacij-cv opt

   spisok-specifikacij-cv:
         const
         volatile

   imya-v-opisatele:
         imya
         imya-klassa
         ~imya-klassa
         imya-typedef
         utochnennoe-imya-tipa

   imya-tipa:
        spisok-specifikacij-tipa abstraktnyj-opisatel' opt

   spisok-specifikacij-tipa:
        specifikaciya-tipa spisok-specifikacij-tipa

   abstraktnyj-opisatel':
        operaciya-ptr abstraktnyj-opisatel' opt
   abstraktnyj-opisatel' opt ( spisok-opisanij-parametrov ) spisok-specifikacij_cv opt
       abstraktnyj-opisatel' opt [ vyrazhenie-konstanta opt ]
       ( abstraktnyj-opisatel' )

   spisok-opisanij-parametrov:
        spisok-opisanij-param opt ... opt
        spisok-opisanij-param , ...

   spisok-opisanij-param:
        opisanie-parametra
        spisok-opisanij-param , opisanie-parametra

   opisanie-parametra:
        specifikacii-opisaniya opisatel'
        specifikacii-opisaniya opisatel' = vyrazhenie
        specifikacii-opisaniya abstraktnyj-opisatel' opt
        specifikacii-opisaniya abstraktnyj-opisatel' opt = vyrazhenie

   opredelenie-funkcii:
        specifikacii-opisaniya opt opisatel' inicializator-ctor telo-funkcii

   telo-funkcii:
        sostavnoj-operator

   inicializator:
         = vyrazhenie-prisvaivaniya
         = { spisok-inicializatorov , opt }
         ( spisok-vyrazhenij )

   spisok-inicializatorov:
         vyrazhenie-prisvaivaniya
         spisok-inicializatorov , vyrazhenie-prisvaivaniya
         { spisok-inicializatorov , opt }



    specifikaciya-klassa:
         zagolovok-klassa { spisok-chlenov opt }

    zagolovok-klassa:
         sluzhebnoe-slovo-klassa identifikator opt spec-bazovyh opt
         sluzhebnoe-slovo-klassa imya-klassa spec-bazovyh opt

    sluzhebnoe-slovo-klassa:
         class
         struct
         union

   spisok-chlenov:
         opisanie-chlena spisok-chlenov opt
         specifikaciya-dostupa : spisok-chlenov opt

   opisanie-chlena:
         specifikacii-opisaniya opt spisok-opisatelej-chlenov opt ;
         opredelenie-funkcii ; opt
         utochnennoe-imya ;

   spisok-opisatelej-chlenov:
         opisatel'-chlena
         spisok-opisatelej-chlenov , opisatel'-chlena

   opisatel'-chlena:
         opisatel' specifikaciya-chistoj opt
         identifikator opt : vyrazhenie-konstanta

   specifikaciya-chistoj:
         = 0

   spisok-bazovyh:
         specifikaciya-bazovyh
         spisok-bazovyh , specifikaciya-bazovyh

   specifikaciya-bazovyh:
         polnoe-imya-klassa
         virtual specifikaciya-dostupa opt polnoe-imya-klassa
         specifikaciya-dostupa virtual opt polnoe-imya-klassa

   specifikaciya-dostupa:
         private
         protected
         public

    imya-funkcii-preobrazovaniya:
         operator imya-tipa-preobrazovaniya

    imya-tipa-preobrazovaniya:
          spisok-specifikacij-tipa operaciya-ptr opt

    inicializator-ctor:
         : spisok-inicializatorov-chlenov

    spisok-inicializatorov-chlenov:
         inicializator-chlena
         inicializator-chlena , spisok-inicializatorov-chlena

    inicializator-chlena:
         polnoe-imya-klassa ( spisok-vyrazhenij opt )
         identifikator

     imya-funkcii-operator:
         operator operaciya

     operaciya: odin iz
               new delete
               +   -   *   /   %   ^   &   |   ~
               !   =   <   >   +=  -=  *=  /=  %=
               ^=  &=  |=  <<  >>  >>= <<= ==  !=
               <=  >=  &&  ||  ++  --  ,   ->* ->
               ()  []



     operator:
         pomechennyj-operator
         operator-vyrazhenie
         sostavnoj-operator
         vybirayushchij-operator
         operator-cikla
         operator-perehoda
         operator-opisaniya

     pomechennyj-operator:
         identifikator : operator
         case vyrazhenie-konstanta : operator
         default : operator

    operator-vyrazhenie:
         vyrazhenie opt ;

    sostavnoj-operator:
         { spisok-operatorov opt }

    spisok-operatorov:
         operator
         spisok-operatorov operator

    vybirayushchij-operator:
         if ( vyrazhenie ) operator
         if ( vyrazhenie ) operator else operator
         switch ( vyrazhenie ) operator

    operator-cikla:
          while ( vyrazhenie ) operator
          do operator  while (vyrazhenie)
          for ( operator-inic vyrazhenie opt ; vyrazhenie opt ) operator

    operator-inic:
          operator-vyrazhenie
          operator-opisanie

     operator-perehoda:
           break ;
           continue ;
           return vyrazhenie opt ;
           goto identifikator ;

     operator-opisaniya:
           opisanie



      #define identifikator stroka-leksem
      #define identifikator ( identifikator , ... , identifikator ) stroka-leksem

      #include "imyafajla"
      #include <imyafajla>

      #line konstanta "imyafajla" opt
      #undef identifikator

      uslovnoe:
           chast'-if chasti-elif opt chast'-else opt stroka-endif

      chast'-if:
           stroka-if tekst

      stroka-if:
           # if vyrazhenie-konstanta
           # ifdef identifikator
           # ifndef identifikator

       chasti-elif:
            stroka-elif tekst
            chasti-elif stroka-elif tekst

       stroka-elif:
            # elif vyrazhenie-konstanta

       chast'-else:
            stroka-else tekst

       stroka-else:
            # else

       stroka-endif:
            # endif



        opisanie-shablona-tipa:
             template < spisok-parametrov-shablona-tipa> opisanie

        spisok-parametrov-shablona-tipa:
             parametr-shablona-tipa
             spisok-parametrov-shablona-tipa , parametr-shablona-tipa

        parametr-shablona-tipa:
             parametr-tipa
             opisanie-parametra

        parametr-tipa:
             class identifikator

         imya-shablonnogo-klassa:
             imya-shablona-tipa < spisok-param-shablona-tipa >

         spisok-param-shablona-tipa:
             param-shablona-tipa
             spisok-param-shablona-tipa , param-shablona-tipa

         param-shablona:
             vyrazhenie
             imya-tipa



         proveryaemyj-blok:
             try sostavnoj-operator spisok-obrabotchikov

         spisok-obrabotchikov:
             obrabotchik spisok-obrabotchikov opt

         obrabotchik:
             catch ( opisanie-osoboj-situacii ) sostavnoj-operator

         opisanie-osoboj-situacii:
             spisok-specifikacij-tipa opisatel'
             spisok-specifikacij-tipa abstraktnyj-opisatel'
             spisok-specifikacij-tipa
                 ...

        vyrazhenie-zapuska:
            throw vyrazhenie opt

        specifikaciya-osoboj-situacii:
            throw ( spisok-tipa opt )

        spisok-tipa:
            imya-tipa
            spisok-tipa , imya-tipa



|to prilozhenie ne otnositsya k spravochnomu rukovodstvu S++ i ne
yavlyaetsya opredeleniem konstrukcij yazyka.
   YAzyk S++ osnovyvaetsya na S (opisanie v knige Kernigana i Ritchi,
78 g., dal'she K&R) i vklyuchaet bol'shinstvo izmenenij, predlozhennyh
v ANSI standarte dlya S. Pri konvertirovanii programm na yazykah
S++, K&R C i ANSI C mogut vozniknut' trudnosti v svyazi s razlichnym
vychisleniem v nih vyrazhenij. Translyator dolzhen raspoznavat' vse razlichiya
mezhdu S++ i ANSI C. Programmy na S++ i ANSI C dolzhny imet' odinakovyj
smysl za isklyucheniem treh sleduyushchih sluchaev:
   V yazyke S vyrazhenie sizeof('a') ravno sizeof(int), a v S++
ono ravno sizeof(char).
   Esli  est' opisanie

       enum e { A };

to sizeof(A) ravno v S sizeof(int), togda kak v S++ ono ravno sizeof(e)
i ne obyazano byt' ravno sizeof(int).
   Imya struktury, opisannoj vo vnutrennem bloke, mozhet skryvat' imya
ob容kta, funkcii, elementa perechisleniya ili tipa iz vneshnego bloka.
Privedem primer:

       int x[99];
       void f()
       {
         struct x { int a; };
         sizeof(x);  /* dlya C eto razmer massiva   */
                     /* a dlya C++ razmer struktury */
        }



V etom razdele perechislyayutsya osnovnye rasshireniya yazyka S, vvedennye
v S++.



Zdes' perechislyayutsya vozmozhnosti, dobavlennye k S, versiej yazyka
S++ 1985 g.
   Mozhno ukazyvat' tipy formal'nyh parametrov funkcii ($$R.8.2.5), i oni
budut proveryat'sya ($$R.5.2.2). Budet proishodit' preobrazovanie
tipa ($$R.5.2.2). |to est' i v ANSI C.
   V vyrazheniyah so znacheniyami tipa float vychisleniya mogut prohodit'
s obychnoj tochnost'yu ($$R.3.6.1 i $$R.4.3). |to est' i v ANSI C.
   Mozhno peregruzhat' imena funkcij; $$R.13.
   Mozhno peregruzhat' operacii; $$R.13.4
   Vozmozhna realizaciya vyzova funkcij podstanovkoj; $$R.7.1.2.
   Mozhno opisyvat' ob容kty, predstavlyayushchie dannye, so specifikaciej
   const; $$R.7.1.6. |to est' i v ANSI C.
   Mozhno opisyvat' tipa ssylki; $$R.8.2.2 i $$R.8.4.3.
   Vozmozhno upravlenie svobodnoj pamyat'yu s pomoshch'yu operacij new i
   delete; $$R.5.3.3 i $$R.5.3.4.
   Vvedeny klassy, kotorye pozvolyayut: skryvat' informaciyu ($$R.11),
   provodit' inicializaciyu ($$R.12.1), osushchestvlyat' pol'zovatel'skie
   preobrazovaniya tipa ($$R.12.3) i rabotat' s dinamicheskimi tipami
   s pomoshch'yu virtual'nyh funkcij ($$R.10.2).
   Imya klassa ili perechisleniya schitaetsya imenem tipa; $$R.9.
   Ukazatel' na lyuboj ob容kt c tipom, ne yavlyayushchimsya const ili volatile,
   mozhno prisvoit' ukazatelyu tipa void*. |to est' i v ANSI C.
   Ukazatel' na funkciyu mozhno prisvaivat' ukazatelyu tipa void*;
   $$R.4.6.
   Opisanie vnutri bloka schitaetsya operatorom; $$R.6.7.
   Mozhno opisyvat' bezymyannye ob容dineniya; $$R.9.5.



Zdes' perechislyayutsya osnovnye rasshireniya S++ posle 1985 g.:
   Klass mozhet imet' bolee odnogo pryamogo bazovogo klassa
(mnozhestvennoe nasledovanie); $$R.10.1.
   CHleny klassa mogut byt' zashchishchennymi; $$R.11.
   Operacii new i delete mozhno opisyvat' v klasse i peregruzhat';
   $$r.5.3.3, $$R.5.3.4, $$R.12.5. |to pozvolilo opredelennyj sposob
upravleniya pamyat'yu dlya klassa s pomoshch'yu "prisvaivaniya ukazatelyu
this" otnesti v razdel anahronizmov; $$R.18.3.3.
   Mozhno yavno unichtozhat' ob容kty; $$R.12.4.
   Prisvaivaniya i inicializaciya dlya klassa opredeleny kak prisvaivanie i
inicializaciya po chlenam; $$R.12.8.
   Sluzhebnoe slovo overload stalo izlishnim i otneseno k razdelu
anahronizmov; $$R.18.3.
   Proizvol'nye vyrazheniya razresheny v kachestve inicializatorov staticheskih
ob容ktov; $$R.8.4.
   Ob容kty, predstavlyayushchie dannye, mogut byt' volatile; $$R.7.1.6.
Takzhe i v ANSI C.
   Dopustimy inicializatory dlya staticheskih chlenov klassa; $$R.9.4.
   Funkcii-chleny mogut byt' staticheskimi; $$R.9.4.
   Funkcii-chleny mogut byt' const ili volatile; $$R.9.3.1.
   Mozhno yavno ukazat' svyazyvanie s podprogrammami na drugih yazykah;
$$R.7.4.
   Mozhno peregruzhat' operacii ->, ->* i ` ; $$R.13.4.
   Klassy mogut byt' abstraktnymi; $$R.10.3.
   Dlya pol'zovatel'skih tipov prefiksnye i postfiksnye operacii
razlichayutsya.
   SHablony tipov; $$R.14.
   Upravlenie osobymi situaciyami; $$R.15.



Voobshche yazyk S++ obladaet bol'shimi vozmozhnostyami i nalagaet men'she
ogranichenij, chem ANSI C, poetomu bol'shinstvo konstrukcij ANSI C
yavlyayutsya zakonnymi dlya S++, prichem smysl ih ne menyaetsya. Isklyucheniya
svoditsya k sleduyushchemu:
   Lyubaya programma na ANSI C, ispol'zuyushchaya v kachestve identifikatorov
sleduyushchie sluzhebnye slova S++, ne yavlyaetsya programmoj na S++; $$R.2.4:

       asm       catch      class       delete     friend
       inline    new        operator    private    protected
       public    template   try         this       virtual
       throw

   Hotya eto schitaetsya ustarevshem v ANSI C, realizaciya S mozhet nalagat'
 drakonovskie ogranicheniya na dlinu identifikatorov; v realizaciyah S++
 eto nedopustimo; $$R.2.3.
   V S++ funkciya dolzhna byt' opisana prezhde, chem ee mozhno vyzvat';
 $$R.5.2.2.
   Opisanie f(); v S++ oznachaet, chto funkciya f ne imeet parametrov
 ($$R.8.2.5), a v S eto oznachaet, chto f mozhet imet' lyuboe chislo
 parametrov lyubogo tipa. Takoe opisanie schitaetsya ustarevshim v ANSI C.
   V ANSI C mozhno neskol'ko raz opisat' bez specifikacii extern global'nyj
 ob容kt dannyh, v S++ vozmozhno tol'ko odno ego opredelenie; $$R.3.3
   V S++ klass ne mozhet imet' tozhe imya, chto i imya typedef, otnosyashcheesya
 v toj zhe oblasti vidimosti k drugomu tipu; $$R.9.1.
   V ANSI C operand tipa void* mozhno ispol'zovat' v pravoj chasti
 prisvaivaniya, a takzhe pri inicializacii peremennoj tipa ukazatelya na
 proizvol'nyj tip; v S++ eto nevozmozhno $$R.7.1.6.
   V ANSI C vozmozhny komandy perehodov, obhodyashchie inicializaciyu;
 v S++ eto nevozmozhno.
   V ANSI C po umolchaniyu global'nyj ob容kt tipa const podlezhit
 vneshnemu svyazyvaniyu; dlya S++ eto ne tak; $$R.3.3.
   Opredeleniya funkcij v "starom" stile i vyzovy neopisannyh funkcij
 schitayutsya v S++ anahronizmami, kotorye ne obyazatel'no dolzhny
 podderzhivat'sya lyuboj realizaciej; $$R.18.3.1. V ANSI C oni prosto
 schitayutsya ustarevshimi.
   V S++ struktura (struct) obrazuet oblast' vidimosti ($$R.3.2);
 V ANSI C struktura, perechislenie ili element perechisleniya,
 opisannye v strukture podnimayutsya v oblast' vidimosti samoj
 struktury.
   Prisvaivanie ob容ktu tipa perechisleniya znacheniya, ne prinadlezhashchego
 perechisleniyu, schitaetsya v S++ anahronizmom i ne dolzhno podderzhivat'sya
 vo vseh realizaciyah; $$R.7.2. V ANSI C rekomenduetsya dlya takih
 prisvaivanij vydavat' preduprezhdenie.
   Stroki, inicializiruyushchie simvol'nye massivy, ne mogut byt' dlinnee
 etih massivov; $$R.8.4.2.
   Tip simvol'noj konstanty v S++ est' char ($$R.2.5.2) i int v
 ANSI C.
   Tip elementa perechisleniya est' tip etogo perechisleniya v S++ ($$R.7.2)
 i tip int v ANSI C.
   Krome togo, standart ANSI dlya S dopuskaet znachitel'nye razlichiya v
dopustimyh realizaciyah yazyka, chto mozhet privesti k eshche bol'shim rashozhdeniyam
mezhdu realizaciyami S++ i S. V chastnosti, v nekotoryh realizaciyah S
mogut byt' dopustimy nekotorye nesovmestimye opisaniya. V S++ trebuetsya
sovmestimost' dazhe dlya raznyh edinic translyacii; $$R.3.3.



V obshchem sluchae programma na S++ ispol'zuet mnogie vozmozhnosti,
otsutstvuyushchie v ANSI C. Dlya takoj programmy neznachitel'nye rashozhdeniya,
perechislennye v $$R.18.2, yavno perekryvayutsya rasshireniyami v S++. Kogda
S++ i ANSI C dolzhny imet' obshchie zagolovochnye fajly, nuzhno pozabotit'sya,
chtoby eti fajly predstavlyali tekst na obshchem podmnozhestve etih yazykov.
   Nel'zya pol'zovat'sya specificheskimi vozmozhnostyami S++ takimi, kak
klassy, peregruzka i t.p.
   Nel'zya ispol'zovat' odno imya dlya oboznacheniya tipa struktury i drugogo
tipa.
   Funkciyu bez parametrov sleduet opisyvat' kak f(void), a ne prosto f().
   Global'nye ob容kty tipa const sleduet yavno specificirovat' kak static
ili extern.
   Dlya razdeleniya chastej programmy na ANSI C i S++ mozhno ispol'zovat'
uslovnuyu translyaciyu s predopisannym imenem __cplusplus.
   Funkcii, kotorye mogut vyzyvat'sya iz programm na obeih yazykah, dolzhny
byt' yavno opisany, kak funkcii, podlezhashchie svyazyvaniyu s S.



Realizaciya S++ mozhet vklyuchat' perechislennye zdes' rasshireniya, chtoby
oblegchit' ispol'zovanie programmy na S, ili chtoby uprostit' perehod
s bolee rannih versij S++. Otmetim, chto s kazhdym rasshireniem svyazany
nezhelatel'nye posledstviya. Esli realizaciya predostavlyaet takoe rasshirenie,
to ona dolzhno takzhe predostavlyat' vozmozhnost' ubedit'sya v otsutstvii
etih posledstvij dlya ishodnoj programmy. Realizaciya S++ ne obyazana
obespechivat' eti rasshireniya.
   Pri opisanii ili opredelenii funkcii mozhno ispol'zovat' slovo overload
 v konstrukcii specifikaciya-opisaniya ($$R.7). Esli ono ispol'zuetsya v
specifikacii-opisaniya, to schitaetsya sluzhebnym slovom i ego nel'zya
ispol'zovat' kak identifikator.
   Opredelenie staticheskogo chlena klassa, predstavlyayushchego dannye,
dlya kotorogo dana standartnaya inicializaciya nulyami ($$R.8.4, $$R.9.4),
mozhet byt' opushcheno.
   Mozhno ispol'zovat' komandy preprocessora starogo stilya (do ANSI C).
   Mozhno prisvaivat' ob容ktu tipa perechisleniya znachenie tipa int.
   Pri udalenii massiva, tip kotorogo ne imeet destruktora, mozhno
ukazyvat' chislo elementov; $$R.5.3.4.
   Odna funkciya operator++() mozhet ispol'zovat'sya dlya peregruzki kak
prefiksnyh, tak i postfiksnyh operacij ++; tozhe verno dlya operacii --;
$$R.13.4.6.



Mozhno ispol'zovat' sintaksis S dlya opredelenij funkcij:

     staroe-opredelenie-funkcii:
          specifikacii-opisanij opt staryj-opisatel'-funkcii
          spisok-opisanij opt telo-funkcii

     staryj-opisatel'-funkcii:
          opisatel' ( spisok-parametrov opt )

     spisok-parametrov:
          identifikator
          spisok-parametrov , identifikator

 Privedem primer:

 max(a,b) int b;  { return (a<b) ? b : a; }

 Esli opredelennaya takim obrazom funkciya ne byla opisana ranee, to tip
 ee formal'nyh parametrov polagaetsya (...), t.e. on ne budet proveryat'sya.
 Esli ona byla opisana, to tip dolzhen soglasovyvat'sya s tipom,
 ukazannym v opisanii.
 Privedennyj sintaksis nel'zya ispol'zovat' dlya opredeleniya funkcij-chlenov.

 R.18.3.2 Staryj stil' zadaniya inicializatora bazovogo klassa

 V konstrukcii inicializator-pamyati ($$R.12.6.2) mozhno ne ukazyvat'
imya-klassa, oboznachayushchee bazovyj klass pri uslovii, chto sushchestvuet
tol'ko odin pryamoj (neposredstvennyj) bazovyj klass. Poetomu v
opisanii

       class B {
          // ...
       public:
          B(int);
       };

       class D : public B {
          // ...
          D(int i) : (i) { /* ... */ }
       };

 budet vyzyvat'sya konstruktor B s parametrom i.

 R.18.3.3 Prisvaivanie ukazatelyu this

 Prisvaivaya opredelennye znacheniya ukazatelyu this, pol'zovatel' mog
 upravlyat' vydeleniem pamyati dlya ob容kta nekotorogo klassa. V
 konstruktore do ispol'zovaniya chlenov klassa mozhno bylo s pomoshch'yu
 takogo prisvaivaniya realizovat' svoj algoritm vydeleniya pamyati.
 Prisvaivaya v destruktore ukazatelyu this nul', mozhno bylo
 obojti standartnuyu operaciyu osvobozhdeniya ob容ktov klassa. Krome
 togo, prisvaivanie nulya v destruktore otmenyalo neyavnye vyzovy
 destruktorov dlya chlenov i bazovyh klassov, naprimer:

        class Z {
          int z[10];
          Z()  { this = my_allocator(sizeof(Z) ); }
          ~Z() { my_deallocator (this); this = 0; }
        };

   Esli vydelenie pamyati uzhe proizoshlo (kak byvaet dlya chlenov i
ob容ktov auto ili static), to pri vhode v konstruktor this imeet
nenulevoe znachenie i znachenie nul' v protivnom sluchae.
   Vyzovy konstruktorov dlya chlenov i bazovyh klassov proizojdut
tol'ko posle togo, kak this poluchil znachenie. Esli v konstruktore
bazovogo klassa est' prisvaivanie this, to novoe znachenie this
budet ispol'zovat'sya i v konstruktorah proizvodnyh klassov, esli
oni est'.
   Otmetim, chto pri nalichii ukazannogo anahronizma ili tip ukazatelya
this ne mozhet byt' *const, ili nuzhno delat' isklyuchenie dlya this iz
pravila o prisvaivanii ukazatelyam so specifikaciej const.



Ukazatel' na funkciyu-chlen nekotorogo ob容kta mozhno privesti k
ukazatelyu na kakuyu-to druguyu funkciyu, naprimer (int (*) ())p->f.
Rezul'tiruyushchij ukazatel' budet nastroen na funkciyu, vyzov kotoroj
budet proishodit' s pomoshch'yu obrashcheniya k etoj funkcii-chlenu dlya
togo zhe ob容kta. Kak obychno rezul'tat takogo vyzova schitaetsya
neopredelennym.




Esli klass opisan vnutri drugogo klassa i v programme bol'she ne
opisano klassov s etim imenem, to ego mozhno ispol'zovat', kak
esli by on byl opisan vne klassa (tak obstoit delo s opisaniem
struct v S), naprimer:

        struct S {
            struct T {
              int a;
            };
            int b;
        };

        struct T x;   // oznachaet `S::T x;'





 auto           avtomaticheskij
 break          razryv
 case           variant
 catch          perehvatit'
 char           simvol
 class          klass
 const          konst
 continue       prodolzhit'
 default        po umolchaniyu
 delete         udalit'
 do             delat'
 double         dvojnoj
 else           inache
 enum           perechislenie
 extern         vneshnij
 float          plavayushchij
 for            dlya
 friend         drug
 goto           perehod na
 if             esli
 inline         podstanovka
 int            celyj
 long           dlinnyj
 new            novyj
 operator       operator
 private        chastnyj
 protected      zashchishchennyj
 public         obshchij
 register       registrovyj
 return         vozvrat
 short          korotkij
 signed         znakovyj
 sizeof         razmer
 static         staticheskij
 struct         struktura
 switch         pereklyuchatel'
 template       shablon tipa
 this           tekushchij
 throw          zapustit'
 try            proverit'
 typedef        tip
 union          ob容dinenie
 unsigned       bezznakovyj
 virtual        virtual'nyj
 void           pustoj
 volatile       izmenyaemyj
 while          poka




        A

abstraktnyj
abstraktnyj klass
abstraktnyj opisatel'
abstraktnyj tip dannyh (ATD)
abstrakciya
abstrakciya dannyh
abstrakciya dannyh ili nasledovanie
avtomaticheskie
agregat
Ada
additivnye operacii
adres
adres bitovogo polya
adres i prisvaivanie
adres konstruktora
Algol68
amerikanskij nacional'nyj institut standartov (ANSI)
anahronizm
analizator rekursivnogo spuska
arifmetika bezznakovogo
arifmetika fiksirovannoj tochnosti
arifmeticheskaya osobaya situaciya
arifmeticheskie operacii s ukazatelem
arifmeticheskie preobrazovaniya
arifmeticheskij tip
assembler
asinhronnye sobytiya
associativnost' operacij
associativnyj massiv
associativnost' operacij

        B

bazovyj
bazovyj klass
bezymyannoe ob容dinenie
bezznakovaya arifmetika
bezznakovaya konstanta
bezznakovyj tip
biblioteka
biblioteka zagolovochnyh fajlov
bitovoe pole
blok
blokirovanie (zamok)
buferizaciya vvoda-vyvoda

        V

vvod vstroennyh tipov
vvod i vyvod
vvod pol'zovatel'skih tipov
vvod-vyvod
virtual'nyj bazovyj klass
virtual'nyj destruktor
virtual'nyj konstruktor
virtual'naya funkciya
vklyuchaemyj fajl
vklyuchenie ishodnogo fajla
vneshnee svyazyvanie
vnutrennee svyazyvanie
vnutrennyaya struktura
vlozhennyj klass
vozvrat karetki
vozvrashchaemoe funkciej znachenie
vos'merichnaya konstanta
vos'merichnoe chislo
vremya zhizni ob容kta
vstroennyj
vstroennaya operaciya
vstroennyj (osnovnoj) tip
vybor chlena klassa
vyvod vstroennyh tipov
vyvod pol'zovatel'skih tipov
vydelenie probelami
vyzov
vyzov virtual'noj funkcii
vyzov destruktora
vyzov operatornoj funkcii
vyzov po znacheniyu
vyzov po ssylke
vyzov funkcii
vyravnivanie
vyravnivanie bitovogo polya
vyravnivanie klassa
vyravnivanie chlena klassa
vyrazhenie
vyrazhenie-zapuska
vyrazhenie konstanta
vyrazhenie-konstanta
vyrazhenie-otnosheniya
vyrazhenie prisvaivaniya
vyrazhenie-privedeniya
vyrazhenie-prisvaivaniya
vyrazhenie-sdviga
vyrazhenie-razmeshcheniya
vychislenie standartnogo parametra
vychitanie ukazatelej

         G
gibridnyj proekt
global'naya oblast' vidimosti
global'naya oblast' vidimosti
global'noe bezymyannoe ob容dinenie
global'noe imya
global'noe imya
global'nye dannye
global'nye ob容kty
glubokoe kopirovanie
gorizontal'naya tabulyaciya \t
gruppirovanie osobyh situacij

         D

dannye
dvojnaya kavychka
desyatichnaya konstanta
destruktor
destruktor vremennogo ob容kta
destruktor lokal'nogo ob容kta
destruktor ob容dineniya
destruktor proizvodnogo klassa
dinamicheskaya inicializaciya
dinamicheskaya informaciya o tipe
dinamicheskij kontrol' tipov
dinamicheskaya oshibka
dlina imeni
dostup
dostup k bazovomu klassu
dostup k virtual'noj funkcii
dostup k zashchishchennomu chlenu
dostup k imeni chlena
dostup k chlenu bazovogo klassa
dostup k chlenu klassa
druzhestvennyj klass
druzhestvennaya funkciya
dostup k virtual'noj funkcii

         E

edinica translyacii

        Z

zavershenie programmy
zagolovochnyj fajl
zagruzchik
zakrytie potoka
zapros resursa
zapusk osoboj situacii
zapusk programmy
zarezervirovannyj identifikator
zashchishchennyj chlen
znakovyj tip

        I
identifikator
ierarhiya klassov
ierarhiya osobyh situacij
ierarhiya ob容ktov
izmenyaemyj adres
imya
imya klassa
imya-klassa
imya peregruzhennogo chlena
imya peregruzhennoj funkcii
imya-prostogo-tipa
imya-shablonnogo-klassa
imya-funkcii-preobrazovaniya
inicializator
inicializaciya
inicializaciya avtomaticheskih
inicializaciya bazovogo klassa
inicializaciya biblioteki
inicializaciya i prisvaivanie
inicializaciya massiva
inicializaciya massiva ob容ktov klassa
inicializaciya massiva simvolov
inicializaciya ob容dineniya
inicializaciya ob容kta klassa
inicializaciya ob容kta-chlena
inicializaciya registra
inicializacii ssylki
inicializaciya struktury
inicializaciya chlena
inicializaciya chlena klassa
inkapsulyaciya
interfejs
interfejs klassa
interfejsnyj klass
ishodnyj fajl
ischerpanie svobodnoj pamyati
ischerpanie resursa
ischerpanie svobodnoj pamyati
iteraciya

        K
karkas oblasti prilozheniya
klass
klass i tip
klass ili ob容dinenie
klass ili struktura
klass osoboj situacii
klass pamyati auto
Kobol
kommentarij
konec stroki \n
konkatenaciya strok
konkretnyj tip
konkretnyj tip dannyh (KTD)
konstanta
konstanta double
konstanta float
konstanta long
konstanta long double
konstanta unsigned
konstanta perechisleniya
konstanta pol'zovatel'skogo tipa
konstanta s plavayushchej tochkoj
konstanta stroka
konstruktor
konstruktor vremennogo ob容kta
konstruktor global'noj peremennoj
konstruktor i abstraktnyj klass
konstruktor kopirovaniya
konstruktor lokal'nogo ob容kta
konstruktor lokal'noj peremennoj
konstruktor ob容dineniya
konstruktor peremennoj iz svobodnoj pamyati
konstruktor proizvodnogo klassa
konstruktor chlena klassa
konstruktor chlenov massiva
kontroliruemoe ob容dinenie
kontrol' diapazona
kontrol' dostupa
kontrol' tipov parametrov funkcii
kopirovanie
kosvennost' (kosvennoe obrashchenie)
kosvennyj bazovyj klass

        L

leksema
leksicheskie soglasheniya
Lisp
literal
literal'nye konstanty
logicheskaya operaciya
lokal'naya oblast' vidimosti

        M

makrokomanda
makrokomanda preprocessora
makrokomanda error
makrokomanda null
makrokomanda pragma
makroobrabotka
makroopredelenie
makropodstanovka
makropodstanovka (podstanovka)
manipulyator
massiv
metka
metka case
metka default
mehanizm vyzova funkcii
metod proektirovaniya
mnogomernyj massiv
mnogosimvol'naya konstanta
mnogourovnevaya obrabotka oshibok
mnozhestvo simvolov ASCII
mnozhestvo simvolov EBCDIC
mnozhestvennoe nasledovanie
model' kaskad
modul'noe programmirovanie
modul'nost'
mul'tiplikativnoe-vyrazhenie

        N

napravlennyj aciklichnyj graf
nasledovanie
nasledovanie destruktora
nasledovanie interfejsa
nasledovanie konstruktora
neodnoznachnoe preobrazovanie tipa
neodnoznachnost'
neodnoznachnost' preobrazovaniya klassa
neozhidannye osobye situacii
neopisannyj parametr
neperehvachennaya osobaya situaciya
neopredelennyj parametr konstruktora
neyavnyj vyzov destruktor
neyavnoe preobrazovanie
neyavnoe preobrazovanie tipa
neyavnoe pol'zovatel'skoe preobrazovanie

        O

obobshchennyj probel
ob容dinenie
oblast' vidimosti
oblast' vidimosti friend
oblast' vidimosti vlozhennogo klassa
oblast' vidimosti imeni
oblast' vidimosti klassa
oblast' vidimosti lokal'nogo klassa
oblast' vidimosti makroimeni
oblast' vidimosti makroopredeleniya
oblast' vidimosti metki
oblast' vidimosti funkcii
oblast' vidimosti standartnogo parametra
obrabotka oshibok
obrabotchik osoboj situacii
obratnaya drobnaya cherta \
obratnyj vyzov
obshirnyj interfejs
obshchij chlen klassa
ob容kt
ob容kt-funkciya
ob容ktno-orientirovannoe programmirovanie
odinochnaya kavychka
okruzhenie programmy
operand const
operand volatile
operand ssylka
operator
operator break
operator continue
operator do
operator for
operator goto
operator if
operator return
operator switch (pereklyuchatel')
operator while
operator vyrazheniya
operator iteracii
operator opisaniya
operator perehoda
operator cikla
operator-vyrazhenie
operator-opisanie
operator-perehoda
operatornaya funkciya (operator)
operacionnaya sistema UNIX
operaciya !
operaciya #
operaciya ##
operaciya %=
operaciya &&
operaciya &=
operaciya *=
operaciya ++
operaciya +=
operaciya ,
operaciya --
operaciya -=
operaciya /=
operaciya ::
operaciya <<=
operaciya >>=
operaciya ^=
operaciya bol'she ili ravno
operaciya bol'she chem
operaciya vvoda >>
operaciya vzyatiya adresa
operaciya vybora chlena klassa
operaciya vyvoda <<
operaciya vyzova funkcii
operaciya dekrement
operaciya zapyataya
operaciya indeksacii
operaciya inkrement
operaciya kosvennosti
operaciya logicheskogo otricaniya
operaciya logicheskoe I
operaciya logicheskoe ILI
operaciya men'she ili ravno
operaciya men'she chem
operaciya neravno
operaciya otnosheniya
operaciya preobrazovaniya
operaciya privedeniya
operaciya ravenstva
operaciya prisvaivaniya
operaciya-prisvaivaniya
operaciya razresheniya oblasti vidimosti
operaciya sdviga vlevo
operaciya slozheniya
operaciya usloviya ( ? : )
operaciya umnozheniya
operaciya unarnyj minus
operaciya delete
operaciya new
operaciya sizeof
opisanie
opisanie asm
opisanie extern
opisanie friend
opisanie register
opisanie typedef
opisanie bitovogo polya
opisanie v kachestve opredeleniya
opisanie vneshnih
opisanie vlozhennogo klassa
opisanie dostupa
opisanie druzhestvennogo klassa
opisanie ili opredelenie
opisanie imeni
opisanie imeni klassa
opisanie klassa
opisanie klassa pamyati
opisanie lokal'nogo klassa
opisanie massiva
opisanie parametra
opisanie postoyannogo ukazatelya
opisanie ssylki
opisanie staticheskogo chlena
opisanie standartnogo parametra
opisanie staticheskogo chlena
opisanie tipa
opisanie ukazatelya
opisanie funkcii
opisanie funkcii-chlena
opisanie chlena
opisanie chlena klassa
opisanie shablona tipa
opisanie-shablona-tipa
opisanie shablonnogo klassa
opisanie shablonnoj funkcii
opisanie ellipsisa v funkcii
opisanie-osoboj-situacii
opisanie-parametra
opisatel'
opisatel'-chlena
opredelenie
opredelenie virtual'noj funkcii
opredelenie klassa
opredelenie konstruktora
opredelenie oblasti vidimosti funkcii
opredelenie ob容kta
opredelenie staticheskogo chlena
opredelenie funkcii
opredelenie-funkcii
opredelenie funkcii-chlena
opredelenie funkcii-chlena inline
opredelenie shablonnogo klassa
opredelenie shablonnoj funkcii
opredelenie chisto virtual'noj funkcii
opredelenie chlena
opredelenie shablonnogo klassa
opredelenie shablonnoj funkcii
opredelenie elementa perechisleniya
osobaya situaciya
osvobozhdenie resursa
osnovnoj tip
otladka
otlichiya ot vychisleniya vyrazhenij v S
otlichiya ot oblasti vidimosti S
otlichiya ot opisaniya funkcii v S
otlichiya ot prostranstva imenovaniya S
otlichiya ot svyazyvaniya v S
oshibka svyazyvaniya

        P
pamyat' dlya klassa
pamyat' dlya massiva
paradigma programmirovaniya
parametr
parametry komandnoj stroki
parametr funkcii
param-shablona-tipa
parametr-shablona-tipa
pervichnoe vyrazhenie
perevod formata \f
peregruzka
peregruzka binarnoj operacii
peregruzka dekrementa
peregruzka i dostup
peregruzka i oblast' vidimosti
peregruzka i ssylka
peregruzka imeni funkcii
peregruzka imeni chlena
peregruzka indeksacii
peregruzka inkrementa
peregruzka operacii
peregruzka operacii vybora chlena
peregruzka operacii vyzova
peregruzka operacii prisvaivaniya
peregruzka unarnoj operacii
peredacha parametra funkcii
pereopredelenie virtual'noj funkcii
perepolnenie
perehvatit' (osobuyu situaciyu)
perechislenie
pobochnye effekty
poverhnostnoe kopirovanie
povtornyj zapusk (osoboj situacii)
podderzhka abstrakcii dannyh
podderzhka ob容ktno-orientirovannogo programmirovaniya
pole
polnoe-imya-klassa
pol'zovatel'skaya operaciya
pol'zovatel'skaya operaciya *=
pol'zovatel'skaya operaciya +
pol'zovatel'skaya operaciya ++
pol'zovatel'skaya operaciya -
pol'zovatel'skaya operaciya --
pol'zovatel'skaya operaciya ->
pol'zovatel'skaya operaciya =
pol'zovatel'skaya operaciya indeksacii
pol'zovatel'skij tip
pol'zovatel'skoe preobrazovanie
pol'zovatel'skaya unarnaya operaciya
pomechennyj operator
porazryadnyj
porazryadnoe I
porazryadnoe vklyuchayushchee ILI
porazryadnoe isklyuchayushchee ILI
porazryadnoe kopirovanie
porazryadnye operacii
porazryadnye logicheskie operacii
poryadok vypolneniya operacij
poryadok vychislenij
poryadok vychisleniya vyrazheniya
poryadok vychisleniya parametrov
posledovatel'nost' razryadov
postoyannoe vyrazhenie
postfiksnoe vyrazhenie
postfiksnye ++ i --
pravila razresheniya peregruzki
pravila oblastej vidimosti
pravila preobrazovaniya tipa
predvaritel'noe opisanie
predvaritel'noe opisanie klassa
predvaritel'noe opisanie shablona tipa
predopredelennaya operaciya vzyatiya adresa
predopredelennoe prisvaivanie
predopredelennye makroimena
preobrazovanie (tipa)
preobrazovanie adresa
preobrazovanie klassa (tipa)
preobrazovanie nulevogo ukazatelya
preobrazovanie ob容kta klassa
preobrazovanie odnogo ukazatelya v drugoj
preobrazovanie parametra
preobrazovanie plavayushchej tochki v celoe
preobrazovanie pol'zovatel'skogo tipa
preobrazovanie pri prisvaivanii
preobrazovanie pustogo ukazatelya
preobrazovanie s pomoshch'yu konstruktora
preobrazovanie ssylki
preobrazovanie tipa vozvrashchaemogo znacheniya
preobrazovaniya tipa parametra funkcii
preobrazovanie ukazatelya
preobrazovanie ukazatelya bazovogo klassa
preobrazovanie ukazatelya v klass
preobrazovanie ukazatelya v funkciyu
preobrazovanie ukazatelya v celoe
preobrazovanie ukazatelya v chlen
preobrazovanie ukazatelya na massiv
preobrazovanie ukazatelya na proizvodnyj klass
preobrazovanie ukazatelya tipa void*
preobrazovanie celogo
preobrazovanie celogo v ukazatel'
prefiksnye ++ i --
privedenie
privedenie adresa
privedenie bazovogo klassa
privedenie ob容kta klassa
privedenie proizvodnogo klassa
privedenie k bazovomu klassu
privedenie odnogo ukazatelya v drugoj
privedenie ssylki
privedenie ukazatelya k funkcii
privedenie ukazatelya k celomu
privedenie ukazatelya k chlenu
privedenie celogo k ukazatelyu
prinadlezhnost'
prinadlezhnost' i nasledovanie
prioritet operacij
prisvaivanie
prisvaivanie i adres
prisvaivanie i inicializaciya
prisvaivanie ssylke
prisvaivanie ukazatelyu
proveryaemyj-blok
proverka tipa standartnogo parametra
programma
programmirovanie
proektirovanie S++
proektirovanie biblioteki
proektirovanie i klassy
proektirovanie i programmirovanie
proektirovanie i yazyk
proektirovanie servisnyh programm
proizvodnyj klass
prototipy
procedurnoe programmirovanie
process razvitiya
pryamoj bazovyj klass
pustaya ochered'
pustoj operator
pustoj spisok parametrov
pustoj parametr
pustoj ukazatel' (NULL)

         R
razbienie osobyh situacij
razbienie programmy
razvitie S++
razdel'naya translyaciya
razmer massiva po umolchaniyu
razmer stroki
razmer struktury
razmer ukazatelya
razmeshchenie
razmnozhenie znaka
razmeshchenie bitovogo polya
razreshenie neodnoznachnosti
razreshenie peregruzki
razreshenie peregruzki shablonnoj
razryad (bit)
razryadnyj vektor
raskruchivanie steka
raspolozhenie bitovyh polej
raspolozhenie ob容ktov klassa
realizaciya
redaktor svyazej
rekursivnyj vyzov funkcii
rekursiya

         S
sborka musora
svobodnaya pamyat'
svodka makrokomand
svodka operatorov
svodka operacij
svodka pravil oblasti vidimosti
svodka sintaksisa vyrazheniya
svyazyvanie
svyazyvanie vneshnih
svyazyvanie lokal'nogo imeni
svyazyvanie staticheskih
svyazyvanie shablona tipa
simvol
simvol shag nazad
simvol'naya konstanta
simvol NULL '\0'
simvol podcherkivaniya _
Simula
sintaksis makroopredelenij (svodka)
sintaksis operatorov
sintaksis vyrazhenij
sintaksis makrokomand
sintaksis operatorov
sintaksis opisanij
sintaksis opisanij klassa
sintaksis opisatelej
sintaksis osobyh situacij
sintaksis shablona tipa
slozhnoe imya klassa
sluzhebnoe slovo
sluzhebnoe slovo class
sovmestimost'
sovmestimost' s ANSI C (svodka)
sovmestimost' s S (svodka)
soglasovannoe svyazyvanie
soprovozhdenie programm
sostavnoj operator
sostoyanie potoka
special'nyj simvol
specifikacii interfejsa
specifikaciya auto
specifikaciya vneshnego svyazyvaniya
specifikaciya dostupa
specifikaciya opisaniya
specifikaciya-bazovyh
specifikaciya-klassa
specifikaciya klassa pamyati
specifikaciya-osoboj-situacii
specifikaciya-opisatelya
specifikaciya-svyazi
specifikaciya svyazi funkcii
specifikaciya-tipa
specifikaciya tipa double
specifikaciya-tipa-char
specifikaciya tipa enum
specifikaciya tipa float
specifikaciya tipa int
specifikaciya tipa short
specifikaciya tipa struct
specifikaciya tipa union
specifikaciya tipa unsigned
specifikaciya tipa void
specifikaciya tipa volatile
specifikaciya funkcii
specifikaciya shablona tipa
specifikaciya friend
specifikaciya inline
specifikaciya pure
specifikaciya-pure
specifikaciya static
specifikaciya typedef
specifikaciya template
specifikaciya virtual
spisok-bazovyh
spisok-vyrazhenij
spisok-inicializatorov
spisok-obrabotchikov
spisok operatornyh funkcij
spisok-opisanij
spisok-opisatelej
spisok-param-shablona-tipa
spisok-parametrov-shablona-tipa
spisok sluzhebnyh slov
spisok-chlenov
sravnenie ukazatelej
sredstva proektirovaniya
ssylka
ssylka const
ssylka volatile
ssylochnoe vyrazhenie
stadii proektirovaniya
stadii razvitiya
stadii translyacii
standartnye biblioteki
standartnyj destruktor
standartnye zagolovochnye fajly
standartnaya inicializaciya
standartnyj katalog include
standartnyj katalog vklyuchaemyh fajlov
standartnyj komponent
standartnyj konstruktor
standartnyj konstruktor kopirovaniya
standartnyj kontrol' dostupa
standartnaya operaciya prisvaivaniya
standartnyj parametr
standartnoe preobrazovanie
standartnoe celochislennoe preobrazovanie
staticheskaya funkciya-chlen
staticheskij klass pamyati
staticheskij kontrol' tipov
staticheskij lokal'nyj ob容kt
staticheskij chlen
staticheskij chlen klassa
stroka formata
strokovyj klass
strokovyj potok
struktura
struktura bloka

      T

telo funkcii
tip
tip bitovogo polya
tip vozvrashchaemogo znacheniya
tip virtual'noj funkcii
tip konstruktora
tip massiva
tip stroki
tip ukazatelya
tip funkcii
tip char
tip double
tip float
tip int
tip long
tip long double
tip short
tip signed char
tip unsigned char
tip void
tip volatile
tochka zapuska
trigraf

       U

uzlovoj klass
ukazanie razmeshcheniya
ukazatel'
ukazatel' na klass
ukazatel' na funkciyu
ukazatel' na funkciyu-chlen
ukazatel' tipa void*
ukazatel' const
unarnoe vyrazhenie
unarnaya operaciya
unarnaya-operaciya
unarnoe vyrazhenie
unarnoe-vyrazhenie
unichtozhenie
unichtozhenie avtomaticheskih
unichtozhenie lokal'noj peremennoj
unichtozhenie lokal'nyh staticheskih
upravlenie
upravlenie pamyat'yu
upravlenie svobodnoj pamyat'yu
upravlyayushchij klass
upravlyayushchaya posledovatel'nost'
upravlyayushchij simvol (\)
upryatyvanie imeni
urovni abstrakcii
uslovnaya translyaciya
uslovnyj
utochnennoe imya
utochnennoe-imya
utochnennoe-imya-klassa
utochnennoe-imya-tipa

       F

fajl i potok
fajlovaya oblast' vidimosti
formatirovannyj vyvod
funkciya
funkcional'naya makrokomanda
funkciya-podstanovka
funkciya-chlen
funkciya-chlen klassa
funkciya-chlen friend
funkciya-chlen inline (podstanovka)
funkciya-chlen lokal'nogo klassa
funkciya-chlen volatile
funkciya-chlen ob容dineniya

       C

celaya konstanta
celi proektirovaniya
celochislennoe preobrazovanie
celochislennyj tip
cikl razvitiya

       CH

chastnyj bazovyj klass
chastnyj chlen klassa
chlen
chlen klassa
chlen proizvodnogo klassa
chisto virtual'naya funkciya

       SH

shablon tipa
shablonnyj klass
shablonnaya funkciya
shablonnaya funkciya-chlen
shagi proektirovaniya
shestnadcaterichnaya konstanta
shirokosimvol'naya stroka

      |

ekvivalentnost' tipov
ekvivalentnost' shablonnyh tipov
element perechisleniya
ellipsis ...

      YA

 yavnoe preobrazovanie tipa
 yavnyj vyzov destruktora
 yavnyj vyzov konstruktora
 yazyk
 yazyk vysokogo urovnya
 yazyk nizkogo urovnya
 yazyk BCPL
 yazyk C++
 yazyk CLU
 yazyk SMALLTALK
 yazyki C i C++

                            A

 abstract                           abstraktnyj
    class                           abstraktnyj klass
 abstract-declarator                abstraktnyj opisatel'
 abstraction                        abstrakciya
    data                            abstrakciya dannyh
    levels                          urovni abstrakcii
 access                             dostup
    base class                      dostup k bazovomu klassu
    base class member               dostup k chlenu bazovogo klassa
    class member                    dostup k chlenu klassa
    control                         kontrol' dostupa
    declaration                     opisanie dostupa
    member name                     dostup k imeni chlena
    protected member                dostup k zashchishchennomu chlenu
    specifier                       specifikaciya dostupa
    virtual function                dostup k virtual'noj funkcii
 Ada                                Ada
 addition operator                  operaciya slozheniya
 additive operators                 additivnye operacii
 address                            adres
 address-of operator                operaciya vzyatiya adresa
 ADT abstract type                  abstraktnyj tip dannyh (ATD)
 aggregate                          agregat
 Algol68                            Algol68
 alignmemt                          vyravnivanie
 allocation                         razmeshchenie
 allocation-expression              vyrazhenie-razmeshcheniya
 ambiguity                          neodnoznachnost'
    resolution                      razreshenie neodnoznachnosti
 ambiguous type conversion          neodnoznachnoe preobrazovanie tipa
 anachronism                        anahronizm
 anonymous union                    bezymyannoe ob容dinenie
 ANSI                               ANSI
 application framework              karkas oblasti prilozheniya
 argument                           parametr
 argument-declaration               opisanie-parametra
 arithmetic                         arifmeticheskij
    conversion                      arifmeticheskoe preobrazovanie
    exception                       arifmeticheskaya osobaya situaciya
    fixed point                     arifmetika fiksirovannoj tochnosti
    pointer                         arifmeticheskie operacii s ukazatelem
    type                            arifmeticheskij tip
    unsigned                        arifmetika bezznakovogo
 array                              massiv
    associative                     associativnyj massiv
    initialization                  inicializaciya massiva
    multidimensional                mnogomernyj massiv
    storage of                      pamyat' dlya massiva
    type                            tip massiva
 arrow operator                     vybor chlena klassa
 ASCII character set                mnozhestvo simvolov ASCII
 asm declaration                    opisanie asm
 assembler                          assembler
 assignment                         prisvaivanie
    and initialization              prisvaivanie i inicializaciya
    and lvalue                      prisvaivanie i adres
 assignment-expression              vyrazhenie-prisvaivaniya
 assignment-operator                operaciya-prisvaivaniya
 associativity of operator          associativnost' operacij
 asynchronous events                asinhronnye sobytiya
 auto                               avtomaticheskie
   destruction                      unichtozhenie avtomaticheskih
   initialization                   inicializaciya avtomaticheskih
   specifier                        specifikaciya auto
   storage class                    klass pamyati auto

                           B

 backslash                          obratnaya drobnaya cherta
 backspace                          simvol shag nazad
 base                               bazovyj
   class                            bazovyj klass
   class access                     dostup k bazovomu klassu
   class cast                       privedenie k bazovomu klassu
 base-list                          spisok-bazovyh
 base-specifier                     specifikaciya-bazovyh
 BCPL                               BCPL
 binding                            svyazyvanie
 bit                                razryad (bit)
   field                            bitovoe pole
   pattern                          posledovatel'nost' razryadov
   vector                           razryadnyj vektor
 bit-field                          bitovoe pole
   address of                       adres bitovogo polya
   alignment                        vyravnivanie bitovogo polya
   declaration                      opisanie bitovogo polya
   layout                           razmeshchenie bitovogo polya
   type                             tip bitovogo polya
 bitwise                            porazryadnyj
   AND operator                     porazryadnoe I
   copy                             porazryadnoe kopirovanie
   exclusive OR operator            porazryadnoe isklyuchayushchee ILI
   inclusive OR operator            porazryadnoe vklyuchayushchee ILI
   logical operators                logicheskie operacii
   operators                        porazryadnye operacii
 block                              blok
   statement { }                    sostavnoj operator
   structure                        struktura bloka
 body, function                     telo funkcii
 break statement                    operator break
 buffering, I/O                     buferizaciya vvoda-vyvoda
 built-in                           vstroennyj
   operator                         vstroennaya operaciya
   type                             vstroennyj (osnovnoj) tip

                         C

 C                                  C
 C ANSI                             C ANSI
   C++                              C i C++
 C++                                C++
    evolution                       razvitie C++
 call                               vyzov
    by reference                    vyzov po ssylke
    by value                        vyzov po znacheniyu
    function                        vyzov funkcii
    operator function               vyzov operatornoj funkcii
 callback                           obratnyj vyzov
 carriage return                    vozvrat karetki
 cast                               privedenie
    base class                      privedenie  bazovogo klassa
    class object                    privedenie  ob容kta klassa
    derived class                   privedenie  proizvodnogo klassa
    integer to pointer              privedenie celogo k ukazatelyu
    operator                        operaciya privedeniya
    pointer to function             privedenie ukazatelya k funkcii
    pointer to integer              privedenie ukazatelya k celomu
    pointer to member               privedenie ukazatelya k chlenu
    pointer to pointer              privedenie odnogo ukazatelya
                                    v drugoj
    reference                       privedenie ssylki
 cast-expression                    vyrazhenie-privedeniya
 catch                              perehvatit'
 CDT concrete type                  konkretnyj tip dannyh (KTD)
 char type                          tip char
    type, signed                    tip signed char
    type specifier                  specifikaciya-tipa-char
    type, unsigned                  tip unsigned char
 character                          simvol
    constant                        simvol'naya konstanta
    set, ASCII                      mnozhestvo simvolov ASCII
    set, EBCDIC                     mnozhestvo simvolov EBCDIC
 class                              klass
    abstract                        abstraktnyj klass
    alignment                       vyravnivanie klassa
    and type                        klass i tip
    base                            bazovyj klass
    constructor and abstract        konstruktor i abstraktnyj klass
    constructor for derived         konstruktor dlya proizvodnogo klassa
    conversion                      preobrazovanie ob容kta klassa
    conversion ambiguity            neodnoznachnost' preobrazovaniya
                                    ob容kta klassa
    declaration                     opisanie klassa
    declaration, forward            predvaritel'noe opisanie klassa
    declaration, friend             opisanie druzhestvennogo klassa
    definition                      opredelenie klassa
    derived                         proizvodnyj klass
    destructor for derived          destruktor proizvodnogo klassa
    exception                       klass osoboj situacii
    friend                          druzhestvennyj klass
    handle                          upravlyayushchij klass
    hierarchy                       ierarhiya klassov
    interface                       interfejs klassa
    member                          chlen klassa
    member access                   dostup k chlenu klassa
    member access operator          operaciya vybora chlena klassa
    member, alignment               vyravnivanie chlena klassa
    member, constructor for         konstruktor chlena klassa
    member declaration              opisanie chlena klassa
    member function                 funkciya-chlen klassa
    member initialization           inicializaciya chlena klassa
    member of derived               chlen proizvodnogo klassa
    member, private                 chastnyj chlen klassa
    member, public                  obshchij chlen klassa
    member, static                  staticheskij chlen klassa
    name                            imya klassa
    name declaration                opisanie imeni klassa
    name, elaborated                slozhnoe imya klassa
    nested                          vlozhennyj klass
    node                            uzlovoj klass
    pointer to                      ukazatel' na klass
    private base                    chastnyj bazovyj klass
    scope                           oblast' vidimosti klassa
    storage                         pamyat' dlya klassa
    template                        shablonnyj klass
    versus struct                   klass ili struktura
    versus union                    klass ili ob容dinenie
    virtual base                    virtual'nyj bazovyj klass
 class-key                          sluzhebnoe slovo class
 class-name                         imya-klassa
 class-specifier                    specifikaciya-klassa
 CLU                                CLU
 Cobol                              Kobol
 comma operator                     operaciya zapyataya
 command line argument              parametry komandnoj stroki
 comment                            kommentarij
 compatibility                      sovmestimost'
     with ANSI C summary            sovmestimost' s ANSI C (svodka)
     with C summary                 sovmestimost' s S (svodka)
 compilation, separate              razdel'naya translyaciya
 complete-class-name                polnoe-imya-klassa
 compound statement                 sostavnoj operator
 concatenation string               konkatenaciya strok
 concrete type                      konkretnyj tip
     type, CDT                      konkretnyj tip dannyh (KTD)
 conditional                        uslovnyj
     compilation                    uslovnaya translyaciya
     expression operator            operaciya usloviya ( ? : )
 constant                           konstanta
     character                      simvol'naya konstanta
     decimal                        desyatichnaya konstanta
     double                         konstanta double
     enumeration                    konstanta perechisleniya
     expression                     vyrazhenie konstanta
     float                          konstanta float
     floating point                 konstanta s plavayushchej tochkoj
     hexadecimal                    shestnadcaterichnaya konstanta
     integer                        celaya konstanta
     long                           konstanta long
     long double                    konstanta long double
     multicharacter                 mnogosimvol'naya konstanta
     octal                          vos'merichnaya konstanta
     of user-defined type           konstanta pol'zovatel'skogo tipa
     unsigned                       konstanta unsigned
 constant-expression                vyrazhenie-konstanta
 constructor                        konstruktor
     address of                     adres konstruktora
     call, explicit                 yavnyj vyzov konstruktora
     conversion by                  preobrazovanie s pomoshch'yu
                                    konstruktora
     copy                           konstruktor kopirovaniya
     default                        standartnyj konstruktor
     default copy                   standartnyj konstruktor kopirovaniya
     definition                     opredelenie konstruktora
     exception handling             konstruktor v obrabotke
                                    osobyh situacij
     for array members              konstruktor chlenov massiva
     for class member               konstruktor chlena klassa
     for derived class              konstruktor proizvodnogo klassa
     for free store variable        konstruktor peremennoj,
                                    razmeshchaemoj v svobodnoj pamyati
     for global variable            konstruktor global'noj peremennoj
     for local variable             konstruktor lokal'noj peremennoj
     for temporary                  konstruktor vremennogo ob容kta
     inheritance                    nasledovanie konstruktorov
     local object                   konstruktor lokal'nogo ob容kta
     type of                        tip konstruktora
     undefined argument to          neopredelennyj parametr konstruktora
     union                          konstruktor ob容dineniya
     virtual                        virtual'nyj konstruktor
 containment                        prinadlezhnost'
     and inheritance                prinadlezhnost' i nasledovanie
 continue statement                 operator continue
 control access                     kontrol' dostupa
 conversion                         preobrazovanie (tipa)
     argument                       preobrazovanie parametra
     arithmetic                     arifmeticheskie preobrazovaniya
     array pointer                  preobrazovanie ukazatelya na massiv
     base class pointer             preobrazovanie ukazatelya
                                    bazovogo klassa
     by assignment                  preobrazovanie pri prisvaivanii
     by constructor                 preobrazovanie konstruktorom
     class                          preobrazovanie klassa (tipa)
     derived class pointer          preobrazovanie ukazatelya
                                    na proizvodnogo klassa
     floating point integer         preobrazovanie znacheniya s
                                    plavayushchej tochkoj v celoe
     implicit                       neyavnoe preobrazovanie
     implicit type                  neyavnoe preobrazovanie tipa
     integer                        preobrazovanie celogo
     integer to pointer             preobrazovanie celogo v ukazatel'
     lvalue                         preobrazovanie adresa
     null pointer                   preobrazovanie pustogo ukazatelya
     of pointer to class            preobrazovanie ukazatelya v klass
     operator                       operaciya preobrazovaniya
     pointer                        preobrazovanie ukazatelya
     pointer to function            preobrazovanie ukazatelya v funkciyu
     pointer to integer             preobrazovanie ukazatelya v celoe
     pointer to member              preobrazovanie ukazatelya v chlen
     pointer to pointer             preobrazovanie odnogo ukazatelya
                                    v drugoj
     reference                      preobrazovanie ssylki
     return type                    preobrazovanie tipa vozvrashchaemogo
                                    znacheniya
     rules, type                    pravila preobrazovaniya tipa
     standard                       standartnoe preobrazovanie
     user-defined                   pol'zovatel'skoe preobrazovanie
     user-defined type              preobrazovanie pol'zovatel'skogo tipa
     void* pointer                  preobrazovanie ukazatelya tipa void*
     zero pointer                   preobrazovanie nulevogo ukazatelya
 conversion-function-name           imya-funkcii-preobrazovaniya
 copy                               kopirovanie
     bitwise                        porazryadnoe kopirovanie
     deep                           glubokoe kopirovanie
     shallow                        poverhnostnoe kopirovanie

                               D

 data                               dannye
     abstraction                    abstrakciya dannyh
     abstraction, support for       podderzhka abstrakcii dannyh
     abstraction vs inheritance     abstrakciya dannyh ili nasledovanie
     global                         global'nye dannye
 debugging                          otladka
 declaration                        opisanie
     access                         opisanie dostupa
     argument                       opisanie parametra
     array                          opisanie massiva
     as definition                  opisanie v kachestve opredeleniya
     asm                            opisanie asm
     bit-field                      opisanie bitovogo polya
     class                          opisanie klassa
     class member                   opisanie chlena klassa
     class name                     opisanie imeni klassa
     constant pointer               opisanie postoyannogo ukazatelya
     default argument               opisanie standartnogo parametra
     definition versus              opisanie ili opredelenie
     ellipsis in function           opisanie ellipsisa v funkcii
     extern                         opisanie extern
     forward                        predvaritel'noe opisanie
     friend                         opisanie friend
     friend class                   opisanie druzhestvennogo klassa
     function                       opisanie funkcii
     function member                opisanie funkcii-chlena
     function template              opisanie shablonnoj funkcii
     local class                    opisanie lokal'nogo klassa
     member                         opisanie chlena
     name                           opisanie imeni
     pointer                        opisanie ukazatelya
     reference                      opisanie ssylki
     register                       opisanie register
     specifier                      specifikaciya opisaniya
     statement                      operator opisaniya
     static member                  opisanie staticheskogo chlena
     storage class                  opisanie klassa pamyati
     syntax summary                 sintaksis opisanij (svodka)
     syntax summary, class          sintaksis opisanij klassa (svodka)
     template                       opisanie shablona tipa
     template class                 opisanie shablonnogo klassa
     template function              opisanie shablonnoj funkcii
     type                           opisanie tipa
     typedef                        opisanie typedef
 declaration                        opisanie
 declaration-list                   spisok-opisanij
 declaration-statement              operator-opisanie
 declarator                         opisatel'
 declarator-list                    spisok-opisatelej
 decl-specifier                     specifikaciya-opisatelya
 decrement operator                 operaciya dekrement
 default access control             standartnyj kontrol' dostupa
      argument                      standartnyj  parametr
      argument evaluation           vychislenie standartnogo parametra
      argument, scope               oblast' vidimosti standartnogo parametra
      argument type checking        proverka tipa standartnogo parametra
      array size                    razmer massiva po umolchaniyu
      assignment operator           standartnaya operaciya prisvaivaniya
      constructor                   standartnyj konstruktor
      copy constructor              standartnyj konstruktor kopirovaniya
      destructor                    standartnyj destruktor
      initialization                standartnaya inicializaciya
 definition                         opredelenie
      class                         opredelenie klassa
      constructor                   opredelenie konstruktora
      enumerator                    opredelenie elementa perechisleniya
      function                      opredelenie funkcii
      function template             opredelenie shablonnoj funkcii
      inline member function        opredelenie funkcii-chlena inline
      member                        opredelenie chlena
      member function               opredelenie funkcii-chlena
      object                        opredelenie ob容kta
      pure virtual function         opredelenie chisto virtual'noj
                                    funkcii
      scope of function             opredelenie oblasti vidimosti
                                    funkcii
      static member                 opredelenie staticheskogo chlena
      template class                opredelenie shablonnogo klassa
      template function             opredelenie shablonnoj funkcii
      virtual function              opredelenie virtual'noj funkcii
 delete operator                    operaciya delete
 dereferencing                      kosvennost' (kosvennoe obrashchenie)
 derived class                      proizvodnyj klass
 design aims                        celi proektirovaniya
      and classes                   proektirovanie i klassy
      and language                  proektirovanie i yazyk
      and programming               proektirovanie i programmirovanie
      library                       proektirovanie biblioteki
      method                        metod proektirovaniya
      of C++                        proektirovanie S++
      stage                         stadii proektirovaniya
      steps                         shagi proektirovaniya
      tools                         sredstva proektirovaniya
 destruction                        unichtozhenie
      of auto                       unichtozhenie avtomaticheskih
      of local static               unichtozhenie lokal'nyh staticheskih
      of local variable             unichtozhenie lokal'noj peremennoj
 destructor                         destruktor
      default                       standartnyj destruktor
      for derived class             destruktor proizvodnogo klassa
      for temporary                 destruktor vremennogo ob容kta
      inheritance                   nasledovanie destruktora
      invocation                    vyzov destruktora
      local object                  destruktor lokal'nogo ob容kta
      virtual                       virtual'nyj destruktor
 development cycle                  cikl razvitiya
      process                       process razvitiya
      stages                        stadii razvitiya
 difference from C expression       otlichiya ot vychisleniya vyrazhenij v S
 evaluation
     from C function declaration    otlichiya ot opisaniya funkcii v S
     from C linkage                 otlichiya ot svyazyvaniya v S
     from C name space              otlichiya ot prostranstva imenovaniya S
     from C scope                   otlichiya ot oblasti vidimosti S
 direct base class                  pryamoj bazovyj klass
 directed acyclic graph             napravlennyj aciklichnyj graf
 directive error preprocessing      makrokomanda error
     pragma preprocessing           makrokomanda pragma
     preprocessing                  makrokomanda preprocessora
 discriminating union               kontroliruemoe ob容dinenie
 discrimination of exceptions       razbienie osobyh situacij
 do statement                       operator do
 double constant                    konstanta double
     type                           tip double
     type specifier                 specifikaciya tipa double
 dynamic type checking              dinamicheskij kontrol' tipov

                            E

 EBCDIC character set               mnozhestvo simvolov EBCDIC
 elaborated class name              slozhnoe imya klassa
 ellipsis ...                       ellipsis ...
 empty argument list                pustoj spisok parametrov
     queue                          pustaya ochered'
     statement                      pustoj operator
 encapsulation                      inkapsulyaciya
 enum type specifier                specifikaciya tipa enum
 enumeration                        perechislenie
     constant                       konstanta perechisleniya
 enumerator                         element perechisleniya
 equality operator                  operaciya ravenstva
 equivalence template type          ekvivalentnost' shablonnyh tipov
     type                           ekvivalentnost' tipov
 error handling                     obrabotka oshibok
     handling, multilevel           mnogourovnevaya obrabotka oshibok
     linkage                        oshibka svyazyvaniya
     preprocessing directive        makrokomanda error
     run-time                       dinamicheskaya oshibka
 escape character                   upravlyayushchij simvol (\)
     sequence                       upravlyayushchaya posledovatel'nost'
 evaluation default argument        vychislenie standartnogo parametra
     of expression, order of        poryadok vychisleniya vyrazheniya
     order of                       poryadok vychislenij
     order of argument              poryadok vychisleniya parametrov
 evolution of S++                   razvitie S++
 exception                          osobaya situaciya
     arithmetic                     arifmeticheskaya osobaya situaciya
     class                          klass osoboj situacii
     handler                        obrabotchik osoboj situacii
     hierarchies                    ierarhiya osobyh situacij
     throwing                       zapusk osoboj situacii
 exception-declaration              opisanie-osoboj-situacii
 exception-specification            specifikaciya-osoboj-situacii
 exhaustion free store              ischerpanie svobodnoj pamyati
 explicit constructor call          yavnyj vyzov konstruktora
     destructor call                yavnyj vyzov destruktora
     type conversion                yavnoe preobrazovanie tipa
 expression                         vyrazhenie
     assignment                     vyrazhenie prisvaivaniya
     constant                       postoyannoe vyrazhenie
     order of evaluation of         poryadok vychisleniya vyrazheniya
     postfix                        postfiksnoe vyrazhenie
     primary                        pervichnoe vyrazhenie
     reference                      ssylochnoe vyrazhenie
     statement                      operator vyrazhenie
     syntax summary                 svodka sintaksisa vyrazheniya
     unary                          unarnoe vyrazhenie
 expression-list                    spisok-vyrazhenij
 expression-statement               operator-vyrazhenie
 extern declaration                 opisanie vneshnih
     linkage                        svyazyvanie vneshnih
     linkage specification          specifikaciya vneshnego svyazyvaniya
 external linkage                   vneshnee svyazyvanie

                             F

 fat interface                       obshirnyj interfejs
 field                               pole
    bit                              bitovoe pole
 fixed point arithmetic              arifmetika s fiksirovannoj tochnost'yu
 float constant                      konstanta float
    type                             tip float
    type specifier                   specifikaciya tipa float
 for statement                       operator for
 format string                       stroka formata
 form feed \f                        perevod formata \f
 forward class declaration           predvaritel'noe opisanie klassa
    declaration                      predvaritel'noe opisanie
    declaration of template          predvaritel'noe opisanie shablona tipa
 free store                          svobodnaya pamyat'
    store exhaustion                 ischerpanie svobodnoj pamyati
    store management                 upravlenie svobodnoj pamyat'yu
 friend                              friend
    class                            druzhestvennyj klass
    declaration                      opisanie friend
    function                         druzhestvennaya funkciya
    member function                  funkciya-chlen friend
    scope of                         oblast' vidimosti friend
    specifier                        specifikaciya friend
 function                            funkciya
    argument                         parametr funkcii
    argument passing                 peredacha parametra funkcii
    argument type checking           kontrol' tipov parametrov funkcii
    argument type conversion         preobrazovaniya tipa parametra
                                     funkcii
    body                             telo funkcii
    call                             vyzov funkcii
    call mechanism                   mehanizm vyzova funkcii
    call, recursive                  rekursivnyj vyzov funkcii
    declaration                      opisanie funkcii
    definition                       opredelenie funkcii
    friend                           druzhestvennaya funkciya
    inline                           funkciya-podstanovka
    inline member                    funkciya-chlen inline (podstanovka)
    linkage specification            specifikaciya svyazi funkcii
    member                           funkciya-chlen
    object                           ob容kt-funkciya
    operator                         operatornaya funkciya (operator)
    pointer to                       ukazatel' na funkciyu
    pointer to member                ukazatel' na funkciyu-chlen
    pure virtual                     chisto virtual'naya funkciya
    scope                            oblast' vidimosti funkcii
    specifier                        specifikaciya funkcii
    template                         shablonnaya funkciya
    type                             tip funkcii
    value return                     vozvrashchaemoe funkciej znachenie
    virtual                          virtual'naya funkciya
 function-definition                 opredelenie-funkcii
 fundamental type                    osnovnoj tip

                             G

 garbage collection                  sborka musora
 global anonymous union              global'noe bezymyannoe ob容dinenie
    data                             global'nye dannye
    name                             global'noe imya
    objects                          global'nye ob容kty
    scope                            global'naya oblast' vidimosti
 goto statement                      operator goto
 greater than operator               operaciya bol'she chem
 greater than or equal operator      operaciya bol'she ili ravno
 grouping of exceptions              gruppirovanie osobyh situacij

                            H
 handle class                        upravlyayushchij klass
 handler, exception                  obrabotchik osoboj situacii
 handler-list                        spisok-obrabotchikov
 header file                         zagolovochnyj fajl
 hexadecimal constant                shestnadcaterichnaya konstanta
 hierarchy class                     ierarhiya klassov
    object                           ierarhiya ob容ktov
 horizontal tab \t                   gorizontal'naya tabulyaciya \t
 hybrid design                       gibridnyj proekt

                            I

 identifier                          identifikator
 if statement                        operator if
 implementation                      realizaciya
 implicit conversion                 neyavnoe preobrazovanie
    destructor call                  neyavnyj vyzov destruktor
    type conversion                  neyavnoe preobrazovanie tipa
    user-defined conversion          neyavnoe pol'zovatel'skoe
                                     preobrazovanie
 include directory, standard         standartnyj katalog include
    file                             vklyuchaemyj fajl
 inclusion source file               vklyuchenie ishodnogo fajla
 increment operator                  operaciya inkrement
 indentation                         vydelenie probelami
 inderect base class                 kosvennyj bazovyj klass
 inderection operator                operaciya kosvennosti
 inequality operator                 operaciya neravno
 inheritance                         nasledovanie
    containment and                  prinadlezhnost' i nasledovanie
    multiple                         mnozhestvennoe nasledovanie
    of constructor                   nasledovanie konstruktora
    of destructor                    nasledovanie destruktora
 initialization                      inicializaciya
    array                            inicializaciya massiva
    array of class objects           inicializaciya massiva ob容ktov klassa
    assignment and                   inicializaciya i prisvaivanie
    character array                  inicializaciya massiva simvolov
    class member                     inicializaciya chlena klassa
    class object                     inicializaciya ob容kta klassa
    default                          standartnaya inicializaciya
    dynamic                          dinamicheskaya inicializaciya
    member                           inicializaciya chlena
    member object                    inicializaciya ob容kta-chlena
    of base class                    inicializaciya bazovogo klassa
    of structure                     inicializaciya struktury
 initializer                         inicializator
 initializer-list                    spisok-inicializatorov
 inline                              inline
    function                         funkciya-podstanovka
    member function                  funkciya-chlen inline
 input and output                    vvod-vyvod
    of built-in type                 vvod vstroennyh tipov
    of user-defined type             vvod pol'zovatel'skih tipov
    operator >>                      operaciya vvoda >>
 int                                 int
   type                              tip int
   type specifier                    specifikaciya tipa int
 integer constant                    celaya konstanta
   conversion                        celochislennoe preobrazovanie
 integral promotion                  standartnoe celochislennoe
                                     preobrazovanie
   type                              celochislennyj tip
 interface                           interfejs
   class                             interfejsnyj klass
   inheritance                       nasledovanie interfejsa
   fat                               obshirnyj interfejs
   specifications                    specifikacii interfejsa
 internal linkage                    vnutrennee svyazyvanie
   structure                         vnutrennyaya struktura
 I/O buffering                       buferizaciya vvoda-vyvoda
 iteration                           iteraciya
   statement                         operator iteracii

                          J

 jump statement                       operator perehoda
 jump-statement                       operator-perehoda

                          K

 keyword                              sluzhebnoe slovo
    list                              spisok sluzhebnyh slov

                          L

 label                                 metka
    case                               metka case
    default                            metka default
    scope of                           oblast' vidimosti metki
 labeled statement                     pomechennyj operator
 language                              yazyk
    design and                         proektirovanie i yazyk
    high-level                         yazyk vysokogo urovnya
    low-level                          yazyk nizkogo urovnya
 layout bit-field                      raspolozhenie bitovyh polej
    class objects                      raspolozhenie ob容ktov klassa
 left shift operator                   operaciya sdviga vlevo
 less than operator                    operaciya men'she chem
    than or equal to operator          operaciya men'she ili ravno
 levels of abstraction                 urovni abstrakcii
 lexical conventions                   leksicheskie soglasheniya
 library                               biblioteka
    design                             proektirovanie biblioteki
    headers                            biblioteka zagolovochnyh fajlov
    initialization                     inicializaciya biblioteki
 lifetime of object                    vremya zhizni ob容kta
 linkage                               svyazyvanie
    consistency                        soglasovannoe svyazyvanie
    error                              oshibka svyazyvaniya
    external                           vneshnee svyazyvanie
    internal                           vnutrennee svyazyvanie
 linker-specification                  specifikaciya-svyazi
 linker                                redaktor svyazej
 Lisp                                  Lisp
 list of operator functions            spisok operatornyh funkcij
 literal                               literal
    constants                          literal'nye konstanty
 loader                                zagruzchik
 local class declaration               opisanie lokal'nogo klassa
    class member function              funkciya-chlen lokal'nogo klassa
    class, scope of                    oblast' vidimosti lokal'nogo klassa
    scope                              lokal'naya oblast' vidimosti
 locking                               blokirovanie (zamok)
 logical AND operator                  operaciya logicheskoe I
    OR operator                        operaciya logicheskoe ILI
    negation operator                  operaciya logicheskogo otricaniya
    operators, bitwise                 porazryadnye logicheskie operacii
 long                                  long
    constant                           konstanta long
    double                             long double
    double constant                    konstanta long double
    double type                        tip long double
    type                               tip long
 loop statement                        operator cikla
 lvalue                                adres
    assignment and                     adres i prisvaivanie
    cast                               privedenie adresa
    conversion                         preobrazovanie adresa
    modifiable                         izmenyaemyj adres

                            M

 macro                                 makrokomanda
    definition, preprocessing          makroopredelenie
    expansion, preprocessing           makropodstanovka
    function-like                      funkcional'naya makrokomanda
    name, scope of                     oblast' vidimosti makroopredeleniya
    names, predefined                  predopredelennye makroimena
    preprocessing                      makroobrabotka
    syntax summary                     sintaksis makroopredelenij (svodka)
 maintenance, software                 soprovozhdenie programm
 management                            upravlenie
    free store                         upravlenie svobodnoj pamyat'yu
    memory                             upravlenie pamyat'yu
 manipulator                           manipulyator
 member                                chlen
 member-declaration                    opisanie-chlena
 member-declarator                     opisatel'-chlena
 member-list                           spisok-chlenov
 modifiable lvalue                     izmenyaemyj adres
 modular programming                   modul'noe programmirovanie
 modularity                            modul'nost'
 multicharacter constant               mnogosimvol'naya konstanta
 multidimensional array                mnogomernyj massiv
 multiple inheritance                  mnozhestvennoe nasledovanie
 multiplication operator               operaciya umnozheniya
 multiplicative-expression             mul'tiplikativnoe-vyrazhenie

                               N

 name                                  imya
    global                             global'noe imya
    hiding                             upryatyvanie imeni
    length of                          dlina imeni
    linkage of local                   svyazyvanie lokal'nogo imeni
    overloaded function                imya peregruzhennoj funkcii
    overloaded member                  imya peregruzhennogo chlena
    qualified                          utochnennoe imya
    scope of                           oblast' vidimosti imeni
 nested class declaration              opisanie vlozhennogo klassa
    class, scope of                    oblast' vidimosti vlozhennogo klassa
 new operator                          operaciya new
 newline \n                            konec stroki \n
 node class                            uzlovoj klass
 null character                        simvol null '\0'
    pointer                            pustoj ukazatel' (null)

                              O

 object                                ob容kt
 object-oriented programming           ob容ktno-orientirovannoe
                                       programmirovanie
 octal constant                        vos'merichnaya konstanta
    number                             vos'merichnoe chislo
 operand const                         operand const
    reference                          operand ssylka
    volatile                           operand volatile
 operator ,                            operaciya ,
    !                                  operaciya !
    #                                  operaciya #
    ##                                 operaciya ##
    %=                                 operaciya %=
    &&                                 operaciya &&
    &=                                 operaciya &=
    *=                                 operaciya *=
    *=, user-defined                   pol'zovatel'skaya operaciya *=
    +, user-defined                    pol'zovatel'skaya operaciya +
    ++                                 operaciya ++
    ++, user-defined                   pol'zovatel'skaya operaciya ++
    +=                                 operaciya +=
    -, user-defined                    pol'zovatel'skaya operaciya -
    --                                 operaciya --
    --, user-defined                   pol'zovatel'skaya operaciya --
    -=                                 operaciya -=
    ->, user-defined                   pol'zovatel'skaya operaciya ->
    /=                                 operaciya /=
    ::                                 operaciya ::
    <<, output                         operaciya vyvoda <<
    <<=                                operaciya <<=
    =, user-defined                    pol'zovatel'skaya operaciya =
    >>, input                          operaciya vvoda >>
    >>=                                operaciya >>=
    ^=                                 operaciya ^=
    address-of                         operaciya vzyatiya adresa
    assignment                         operaciya prisvaivaniya
    associativity                      associativnost' operacij
    binding strength                   poryadok vypolneniya operacij
    built-in                           vstroennye operacii
    function call                      operaciya vyzova funkcii
    precedence                         prioritet operacij
    sizeof                             operaciya sizeof
    subscripting                       operaciya indeksacii
    summary                            svodka operacij
    user-defined                       pol'zovatel'skaya operaciya
 operator function                     operatornaya funkciya
    function, list of                  spisok operatornyh funkcij
 order of argument evaluation          poryadok vychisleniya parametrov
    of evaluation                      poryadok vychislenij
 output formatted                      formatirovannyj vyvod
    input and                          vvod i vyvod
    of built-in type                   vyvod vstroennyh tipov
    of user-defined type               vyvod pol'zovatel'skih tipov
    operator <<                        operaciya vyvoda <<
 overflow                              perepolnenie
 overloaded assignment operator        peregruzka operacii prisvaivaniya
    binary operator                    peregruzka binarnoj operacii
    decrement operator                 peregruzka dekrementa
    function call operator             peregruzka operacii vyzova
    function name                      peregruzka imeni funkcii
    increment operator                 peregruzka inkrementa
    member access operator             peregruzka operacii vybora chlena
    member name                        peregruzka imeni chlena
    operator                           peregruzka operacii
    subscripting operator              peregruzka indeksacii
    unary operator                     peregruzka unarnoj operacii
 overloading                           peregruzka
    and access                         peregruzka i dostup
    and scope                          peregruzka i oblast' vidimosti
    resolution                         razreshenie peregruzki
    resolution rules                   pravila razresheniya peregruzki
 overriding virtual function           pereopredelenie virtual'noj
                                       funkcii

                                P

 paradigm, programming                 paradigma programmirovaniya
 placement                             ukazanie razmeshcheniya
 pointer                               ukazatel'
    arithmetic                         arifmeticheskie operacii ukazatelej
    assignment to                      prisvaivanie ukazatelyu
    comparison                         sravnenie ukazatelej
    const                              ukazatel' const
    conversion                         preobrazovanie ukazatelej
    declaration                        opisanie ukazatelya
    null                               pustoj ukazatel' null
    size of                            razmer ukazatelya
    substraction                       vychitanie ukazatelej
    type                               tip ukazatelya
 postfix ++ and --                     postfiksnye ++ i --
    expression                         postfiksnoe vyrazhenie
 precedence of operator                prioritet operacij
 predefined address-of operator        predopredelennaya operaciya
                                       vzyatiya adresa
    assignment operator                predopredelennoe prisvaivanie
    macronames                         predopredelennye makroimena
 prefix ++ and --                      prefiksnye ++ i --
 preprocessing                         makroobrabotka
    directive                          makrokomanda
    directive, error                   makrokomanda error
    directive, null                    makrokomanda null
    directive, pragma                  makrokomanda pragma
    macro definition                   makroopredelenie
    macro expansion                    makropodstanovka (podstanovka)
    syntax summary                     svodka makrokomand
 primary expression                    pervichnoe vyrazhenie
 private                               private
    base class                         chastnyj bazovyj klass
    class member                       chastnyj chlen klassa
 procedural programming                procedurnoe programmirovanie
 program                               programma
    environment                        okruzhenie programmy
    partitioning                       razbienie programmy
    start                              zapusk programmy
    termination                        zavershenie programmy
 protected                             protected
    member                             zashchishchennyj chlen
    member access                      dostup k zashchishchennomu chlenu
 prototypes                            prototipy
 public                                public
    class member                       obshchij chlen klassa
 pure specifier                        specifikaciya pure
    virtual function                   chisto virtual'naya funkciya
 pure-specifier                        specifikaciya-pure

                          Q

 qualified name                        utochnennoe imya
 qualified-class-name                  utochnennoe-imya-klassa
 qualified-name                        utochnennoe-imya
 qualified-type-name                   utochnennoe-imya-tipa
 queue empty                           pustaya ochered'
 quote, single                         odinochnaya kavychka
    double                             dvojnaya kavychka

                           R

 range checking                        kontrol' diapazona
 recursion                             rekursiya
 recursive decent parser               analizator rekursivnogo spuska
    function call                      rekursivnyj vyzov funkcii
 reference                             ssylka
    assignment                         prisvaivanie ssylki
    assignment to                      prisvaivanie ssylke
    call by                            vyzov po ssylke
    cast                               privedenie ssylki
    conversion                         preobrazovanie ssylki
    const                              ssylka const
    declaration                        opisanie ssylki
    initialization                     inicializacii ssylki
    operand                            operand ssylka
    overloading and                    peregruzka i ssylka
    volatile                           ssylka volatile
 register declaration                  opisanie register
    initialization                     inicializaciya registra
 relational operator                   operaciya otnosheniya
 relational-expression                 vyrazhenie-otnosheniya
 reserved identifier                   zarezervirovannyj identifikator
 resolution ambiguity                  razreshenie neodnoznachnosti
    scoping ambiguity                  razreshenie neodnoznachnosti
                                       oblasti vidimosti
    template function overloading      razreshenie peregruzki shablonnoj
                                       funkcii
 resource acquisition                  zapros resursa
    exhaustion                         ischerpanie resursa
    release                            osvobozhdenie resursa
 re-throw                              povtornyj zapusk (osoboj situacii)
 return                                return
 return statement                      operator return
 return type                           tip vozvrashchaemogo znacheniya
 run-time error                        dinamicheskaya oshibka
    initialization                     dinamicheskaya inicializaciya
    type information                   dinamicheskaya informaciya o tipe

                               S

 scope                                 oblast' vidimosti
    class                              oblast' vidimosti klassa
    file                               fajlovaya oblast' vidimosti
    function                           oblast' vidimosti funkcii
    global                             global'naya oblast' vidimosti
    local                              lokal'naya oblast' vidimosti
    of label                           oblast' vidimosti metki
    of local class                     oblast' vidimosti lokal'nogo klassa
    of macro name                      oblast' vidimosti makroimeni
    of name                            oblast' vidimosti imeni
    of nested class                    oblast' vidimosti vlozhennogo klassa
    resolution operator                operaciya razresheniya oblasti
                                       vidimosti
    rules summary                      svodka pravil oblasti vidimosti
 separate compilation                  razdel'naya translyaciya
 shift-expression                      vyrazhenie-sdviga
 short type                            tip short
    type specifier                     specifikaciya tipa short
 side effects                          pobochnye effekty
 sign extension                        razmnozhenie znaka
 signed char type                      tip signed char
    type                               znakovyj tip
 simple-type-name                      imya-prostogo-tipa
 Simula                                Simula
 size of pointer                       razmer ukazatelya
    of string                          razmer stroki
    of structure                       razmer struktury
 sizeof operator                       operaciya sizeof
 Smalltalk                             Smalltalk
 source file                           ishodnyj fajl
    file, inclusion                    vklyuchenie ishodnogo fajla
 special character                     special'nyj simvol
 specifier auto                        specifikaciya auto
    declaration                        specifikaciya opisaniya
    friend                             specifikaciya friend
    function                           specifikaciya funkcii
    inline                             specifikaciya inline
    static                             specifikaciya static
    storage class                      specifikaciya klassa pamyati
    template                           specifikaciya shablona tipa
    typedef                            specifikaciya typedef
    virtual                            specifikaciya virtual
 stack unwinding                       raskruchivanie steka
 standard component                    standartnyj komponent
    conversion                         standartnoe preobrazovanie
    headers                            standartnye zagolovochnye fajly
    include directory                  standartnyj katalog vklyuchaemyh
                                       fajlov
    libraries                          standartnye biblioteki
 statement                             operator
    break                              operator break
    compound                           sostavnoj operator
    continue                           operator continue
    declaration                        operator opisaniya
    do                                 operator do
    empty                              pustoj operator
    expression                         operator vyrazheniya
    for                                operator for
    goto                               operator goto
    if                                 operator if
    summary                            svodka operatorov
    switch                             operator switch (pereklyuchatel')
    syntax summary                     sintaksis operatorov
    while                              operator while
 static type checking                  staticheskij kontrol' tipov
 static                                static
    class member                       staticheskij chlen klassa
    linkage of                         svyazyvanie staticheskih
    local object                       staticheskij lokal'nyj ob容kt
    member                             staticheskij chlen
    member declaration                 opisanie staticheskogo chlena
    member definition                  opredelenie staticheskogo chlena
    member function                    staticheskaya funkciya-chlen
    specifier                          specifikaciya static
    storage class                      staticheskij klass pamyati
 stream closing of                     zakrytie potoka
    file and                           fajl i potok
    state                              sostoyanie potoka
    string                             strokovyj potok
 string class                          strokovyj klass
    concatenation                      konkatenaciya strok
    constant                           konstanta stroka
    type of                            tip stroki
    wide-character                     shirokosimvol'naya stroka
 struct                                struct
    type specifier                     specifikaciya tipa struct
 structure                             struktura
    initialization of                  inicializaciya struktury
 subclass                              vlozhennyj klass
 subscripting user-defined             pol'zovatel'skaya operaciya indeksacii
 summary class declaration syntax      sintaksis opisanij klassa
    compatibility with ANSI C          sovmestimost' s ANSI C
    compatibility with C               sovmestimost' s S
    declaration syntax                 sintaksis opisanij
    declarator syntax                  sintaksis opisatelej
    exception handling syntax          sintaksis osobyh situacij
    expression syntax                  sintaksis vyrazhenij
    macro syntax                       sintaksis makrokomand
    scope rules                        pravila oblastej vidimosti
    statement syntax                   sintaksis operatorov
    template syntax                    sintaksis shablonov tipa
 support for data abstraction          podderzhka abstrakcii dannyh
 for object-oriented programming       podderzhka ob容ktno-orientirovannogo
                                       programmirovaniya

                                 T

 template                              shablon tipa
    class                              shablonnyj klass
    class declaration                  opisanie shablonnogo klassa
    class definition                   opredelenie shablonnogo klassa
    declaration                        opisanie shablona tipa
    function                           shablonnaya funkciya
    function declaration               opisanie shablonnoj funkcii
    function definition                opredelenie shablonnoj funkcii
    linkage of                         svyazyvanie shablona tipa
    member function                    shablonnaya funkciya-chlen
    specifier                          specifikaciya template
    syntax summary                     sintaksis shablona tipa
 template-arg                          param-shablona-tipa
 template-arg-list                     spisok-param-shablona-tipa
 template-argument                     parametr-shablona-tipa
 template-argument-list                spisok-parametrov-shablona-tipa
 template-class-name                   imya-shablonnogo-klassa
 template-declaration                  opisanie-shablona-tipa
 temporary                             vremennyj ob容kt
 this                                  this
 throw                                 throw
 throw-expression                      vyrazhenie-zapuska
 throwing, exception                   zapusk osoboj situacii
 throw-point                           tochka zapuska
 token                                 leksema
 tools design                          proektirovanie servisnyh programm
 translation phases                    stadii translyacii
    unit                               edinica translyacii
 trigraph                              trigraf
 try                                   try
 try-block                             proveryaemyj-blok
 type                                  tip
    user-defined                       pol'zovatel'skij tip
 type-specifier                        specifikaciya-tipa

                             U

 unary expression                      unarnoe vyrazhenie
     minus operator                    operaciya unarnyj minus
     operator                          unarnaya operaciya
     operator, user-defined            pol'zovatel'skaya unarnaya operaciya
     plus, operator                    operaciya unarnyj plyus
 unary-expression                      unarnoe-vyrazhenie
 unary-operator                        unarnaya-operaciya
 uncaught exception                    neperehvachennaya osobaya situaciya
 undeclared argument                   neopisannyj parametr
 underscore character                  simvol podcherkivaniya _
 unexpected exceptions                 neozhidannye osobye situacii
 union                                 ob容dinenie
    anonymous                          bezymyannoe ob容dinenie
    constructor                        konstruktor ob容dineniya
    destructor                         destruktor ob容dineniya
    discriminating                     kontroliruemoe ob容dinenie
    initialization                     inicializaciya ob容dineniya
    member function                    funkciya-chlen ob容dineniya
    type specifier                     specifikaciya tipa union
 UNIX                                  UNIX
 unsigned arithmetic                   bezznakovaya arifmetika
    char type                          tip unsigned char
    constant                           bezznakovaya konstanta
    type                               bezznakovyj tip
    type specifier                     specifikaciya tipa unsigned

                            V

 vertical tab \v                       vertikal'naya tabulyaciya \v
 virtual                               virtual
    base class                         virtual'nyj bazovyj klass
    destructor                         virtual'nyj destruktor
    function                           virtual'naya funkciya
    function access                    dostup k virtual'noj funkcii
    function call                      vyzov virtual'noj funkcii
    function, type of                  tip virtual'noj funkcii
    specifier                          specifikaciya virtual
    user-defined conversion            virtual'noe pol'zovatel'skoe
                                       preobrazovanie
 void                                  void
    argument                           pustoj parametr
    pointer to                         ukazatel' tipa void*
    type                               tip void
    type specifier                     specifikaciya tipa void
 volatile                              volatile
    member function                    funkciya-chlen volatile
    operand                            operand volatile
    reference                          ssylka volatile
    type                               tip volatile
    type specifier                     specifikaciya tipa volatile

                              W

 waterfall model                       model' kaskad
 white space                           obobshchennyj probel
 wide-character string                 shirokosimvol'naya stroka






#include <stream.hxx>

main()
{
    cout << "Hello, world\n";
}




#include <stream.hxx>

main ()
{
 int inch = 0;
 cout << "inches=";
 cin  >> inch;
 cout << inch;
 cout << "in = ";
 cout << inch*2.54;
 cout << " cm\n";
}




#include <stream.hxx>

main()
{
 const float fac = 2.54;
 float x, in, cm;
 char ch = 0;

for ( int i= 0; i< 8; i++) {
 cerr << "enter length: ";
 cin >> x >> ch;

 if (ch == 'i' ) {   // inch
    in = x;
    cm = x*fac;
 }
 else if (ch == 'c') { // cm
     in = x/fac;
     cm = x;
 }
 else
    in = cm = 0;

 cerr << in << "in = " << cm << " cm\n";
}
}




#include <stream.hxx>
extern float pow(float, int);

main()
{
 for (int i=0; i<10; i++) cout << pow(2,i) << "\n";
}

extern void error(char *);

float pow(float x, int n)
{
  if (n < 0)  {
     error ("sorry, negative exponent to pow()");
     return 0;
     }

  switch (n) {
  case 0:   return 1;
  case 1:   return x;
  default:  return x*pow(x,n-1);
  }
}

void error(char *s)
{
 cout << s;
}




#include <stream.hxx>

// 1.11
class vector {
  int *v;
  int sz;
public:
       vector(int);   // constructor
       ~vector();    // destructor
  int size() { return sz; }
  void set_size(int);
  int& operator[](int);
  int& elem(int i) { return v[i]; }
};

// 1.13
class vec : public vector {
  int low, high;
public:
  vec(int, int);
  int& elem(int);
  int& operator[](int);
};


main()
{
 vector a(10);
 for (int i=0; i<a.size(); i++) {
     a[i] = i;
     cout << a[i] << " ";
 }
 cout << "\n";
 vec b(10,19);
 for (i=0; i<b.size(); i++) b[i+10] = a[i];
 for (i=0; i<b.size(); i++) cout << b[i+10] << " ";
 cout << "\n";
}

extern void exit(int);
// 1.13
void error(char* p)
{
cerr << p << "\n";
exit (1);
}

// 1.11
vector::vector(int s)
{
  if (s<=0) error("bad vector size");
  sz = s;
  v = new int[s];
}

int& vector::operator[](int i)
{
   if (i<0 || sz<=i) error("vector index out of range");
   return v[i];
}

vector::~vector()
{
  delete v;
}

// 1.13
int& vec::elem(int i)
{
  return vector::elem(i-low);
}

vec::vec(int lb, int hb) : (hb-lb+1)
{
  if (hb-lb<0) hb = lb;
  low = lb;
  high = hb;
}

void vector::set_size(int) { /* dummy */ }

int& vec::operator[](int i)
{
 if (i<low || high<i) error("vec index out of range");
 return elem(i);
}




#include<stream.hxx>

extern void exit( int );
extern void error( char* );

// 1.11
class vector {
  int *v;
  int sz;
public:
       vector(int);   // constructor
       ~vector();    // destructor
  int size() { return sz; }
  void set_size(int);
  int& operator[](int);
  int& elem(int i) { return v[i]; }
};

vector::vector(int s)
{
  if (s<=0) error("bad vector size");
  sz = s;
  v = new int[s];
}

int& vector::operator[](int i)
{
   if (i<0 || sz<=i) error("vector index out of range");
   return v[i];
}

vector::~vector()
{
  delete v;
}

// 1.14
class Vec : public vector {
public:
  Vec(int s) : (s) {}
  Vec(Vec&);
  ~Vec() {}
  void operator=(Vec&);
  void operator*=(Vec&);
  void operator*=(int);
};

Vec::Vec(Vec& a) : (a.size())
{
int sz = a.size();
for (int i = 0; i<sz; i++) elem(i) =a.elem(i);
}

void Vec::operator=(Vec& a)
{
 int s = size();
 if (s!=a.size()) error("bad vector size for =");
 for (int i =0; i<s; i++) elem(i)=a.elem(i);
}

Vec operator+(Vec& a, Vec& b)
{
 int s = a.size();
 if (s != b.size()) error("bad vector size for +");
 Vec sum(s);
 for (int i=0; i<s; i++)
    sum.elem(i) = a.elem(i) + b.elem(i);
 return sum;
}


void error(char* p)
{
cerr << p << "\n";
exit (1);
}

void vector::set_size(int) {  }

main()
{
 Vec a(10);
 Vec b(10);
 for (int i=0; i<a.size(); i++) a[i] = i;
 b = a;
 Vec c = a+b;
 for (i=0; i<c.size(); i++) cout << c[i] << "\n";
}




#include <vector.hxx>

declare(vector,int);
implement(vector,int);

main()
{
  vector(int) vv(10);
  vv[2] = 3;
  vv[10] = 4;		// range error
}




#include <stream.hxx>

int a = 1;

void f()
{
  int b = 1;
  static int c = 1;
  cout << " a = " << a++
       << " b = " << b++
       << " c = " << c++ << "\n";
}

main ()
{
 while (a < 4) f();
}




#include <stream.hxx>

main()
{
 int* p = new int;
 cout << "sizeof(int) = " << sizeof(int) "\n";
}




#include <stream.hxx>

extern int strlen(char*);

char alpha[] = "abcdefghijklmnopqrstuvwxyz";

main ()
{
 int sz = strlen(alpha);

 for (int i=0; i<sz; i++) {
     char ch = alpha[i];
     cout << "'" << chr(ch) << "'"
          << " = " << ch
          << " = 0" << oct(ch)
          << " = 0x" << hex(ch) << "\n";
 }
}




#include <stream.hxx>

char v[2][5] = {
   'a', 'b', 'c', 'd', 'e',
   '0', '1', '2', '3', '4'
};

main() {
 for ( int i = 0; i<2; i++) {
     for (int j = 0; j <5; j++)
         cout << "v[" << i << "][" << j
              << "]=" << chr(v[i][j]) << "  ";
    cout << "\n";
}
}




#include <stream.hxx>

main()
{
  char cv[10];
  int iv[10];

  char* pc = cv;
  int* pi = iv;

 cout << "char* " << long(pc+1)-long(pc) << "\n";
 cout << "int* "  << long(pi+1)-long(pi) << "\n";
}




#include <stream.hxx>

struct pair {
    char* name;
    int val;
};
extern int strlen(char*);
extern int strcpy(char*, char*);
extern int strcmp(char*, char*);

const large = 1024;
static pair vec[large];

pair* find(char* p)
{
 for (int i=0; vec[i].name; i++)
     if (strcmp(p,vec[i].name)==0) return &vec[i];

 if (i== large) return &vec[large-1];

 return &vec[i];
}

int& value(char* p)
{
  pair* res = find(p);
  if (res->name == 0) {
     res->name = new char[strlen(p)+1];
     strcpy(res->name,p);
     res->val = 0;
  }
  return res->val;
}

const MAX = 256;


main ()
{
 char buf [MAX];

 while ( cin>>buf) value(buf)++;

 for (int i=0; vec[i].name; i++)
   cout << vec[i].name << ":" << vec[i].val << "\n";
}




#include <xstream.hxx>
#include <ctype.h>

enum token_value {
   NAME,  NUMBER, END,
   PLUS = '+',  MINUS = '-',  MUL='*',     DIV='/',
   PRINT=';',    ASSIGN='=',  LP='(',   RP=')'
};

token_value curr_tok;

struct name {
  char* string;
  name* next;
  double value;
};


const TBLSZ = 23;
name* table[TBLSZ];

int no_of_errors;

double error(char* s) {
  cerr << "error: " << s << "\n";
  no_of_errors++;
  return 1;
}

extern int strlen(const char*);
extern int strcmp(const char*, const char*);
extern char* strcpy(char*, const char*);

name* look(char* p, int ins = 0)
{
  int ii= 0;
  char *pp = p;
  while (*pp) ii = ii<<1 ^ *pp++;
  if (ii < 0) ii = -ii;
  ii %= TBLSZ;

  for (name* n=table [ii]; n; n=n->next)
      if (strcmp(p,n->string) == 0) return n;

  if (ins == 0) error("name not found");

  name* nn = new name;
  nn->string = new char[strlen(p) + 1];
  strcpy(nn->string,p);
  nn->value = 1;
  nn->next = table[ii];
  table[ii] = nn;
  return nn;
}

inline name* insert(char* s) { return look (s,1); }

token_value get_token();
double term();

double expr()
{
  double left = term();

  for (;;)
      switch (curr_tok) {
      case PLUS:
           get_token();
           left += term();
           break;
      case MINUS:
           get_token();
           left -= term();
           break;
      default :
           return left;
      }
}

double prim();

double term()
{
  double left = prim();

  for (;;)
      switch (curr_tok) {
      case MUL:
           get_token();
           left *= prim();
           break;
      case DIV:
           get_token();
           double d = prim();
           if (d == 0) return error("divide by o");
           left /= d;
           break;
      default:
           return left;
      }
}
int number_value;
char name_string[80];

double prim()
{
  switch (curr_tok) {
  case NUMBER:
       get_token();
       return number_value;
  case NAME:
       if (get_token() == ASSIGN) {
          name* n = insert(name_string);
          get_token();
          n->value = expr();
          return n->value;
       }
       return look(name_string)->value;
  case MINUS:
       get_token();
       return -prim();
  case LP:
       get_token();
       double e = expr();
       if (curr_tok != RP) return error(") expected");
       get_token();
       return e;
  case END:
       return 1;
  default:
       return error ("primary expected");
  }
}

token_value get_token()
{
 char ch = 0;

 do {
    if(!cin.get(ch)) return curr_tok = END;
 } while (ch!='\n' && isspace(ch));

 switch (ch) {
 case ';':
 case '\n':
      cin >> WS;
      return curr_tok=PRINT;
 case '*':
 case '/':
 case '+':
 case '-':
 case '(':
 case ')':
 case '=':
      return curr_tok=ch;
 case '0': case '1': case '2': case '3': case '4':
 case '5': case '6': case '7': case '8': case '9':
 case '.':
    cin.putback(ch);
    cin >> number_value;
    return curr_tok=NUMBER;
 default:
   if (isalpha(ch)) {
      char* p = name_string;
      *p++ = ch;
      while (cin.get(ch) && isalnum(ch)) *p++ = ch;
      cin.putback(ch);
      *p = 0;
      return curr_tok=NAME;
   }
   error ("bad token");
   return curr_tok=PRINT;
  }
}

int main(int argc, char* argv[])
{
  switch (argc) {
  case 1:
     break;
  case 2:
     cin = *new istream(strlen(argv[1]),argv[1]);
     break;
  default:
     error("too many arguments");
     return 1;
  }

  // insert predefined names:
  insert("pi")->value = 3.1415926535897932385;
  insert("e")->value = 2.7182818284590452354;

  while (1) {
     get_token();
     if( curr_tok == END) break;
     if (curr_tok == PRINT) continue;
     cout << expr() << "\n";
  }

  return no_of_errors;
}




extern void strcpy(char *,char *);
extern void exit(int);
extern int strlen(char *);

char *save_string(char* p)
{
 char* s = new char[strlen(p)+1];
 strcpy(s,p);
 return s;
}

int main (int argc, char* argv[])
{
  if (argc < 2) exit(1);
  int size = strlen(argv[1])+1;
  char* p = save_string (argv[1]);
  delete[size] p;
}




#include <stream.hxx>

extern void exit( int );
void out_of_store()
{

  cout << "operator new failed: out of store\n";
  exit(1);
}

typedef void (*PF)();

extern PF set_new_handler(PF);

main()
{
  set_new_handler(&out_of_store);
  char *p = new char[100000000];
  cout << "done, p = " << long(p) << "\n";
}




// This version of the program does not assume sizeof(int)==sizeof(char*) !

#include <stream.hxx>
#include <stdarg.hxx>

extern void exit(int);
void error (int ...);

main(int argc, char* argv[])
{
  switch (argc) {
  case 1:
      error(0,argv[0],(char*)0);
      break;
  case 2:
      error(0,argv[0],argv[1],(char*)0);
      break;
  default :
     error(1,"with",dec(argc-1),"arguments",(char*)0);
  }
}


void error(int n ...)
{
 va_list ap;
 va_start(ap,n);

 for (;;) {
     char *p = va_arg(ap,char*);
     if (p == 0) break;
     cerr << p << " ";
 }

 va_end(ap);

 cerr << "\n";
 if (n) exit(n);
}


#include <stream.hxx>

struct user {
   char *name;
   char* id;
   int dept;
};

typedef user* Puser;

user heads[] = {
 "Mcilroy M.D",     "doug", 11271,
 "Aho A.v.",        "ava",  11272,
 "Weinberger P.J.", "pjw",  11273,
 "Schryer N.L.",    "nls",  11274,
 "Schryer N.L.",    "nls",  11275,
 "Kernighan B.W.",  "bwk",  11276
};

typedef int (*CFT)(char*,char*);

void sort(char* base, unsigned n, int sz, CFT cmp)
{
 for (int i=0; i<n-1; i++)
     for (int j=n-1; i<j; j--) {
         char* pj = base+j*sz;
         char *pj1 = pj-sz;
         if ((*cmp)(pj,pj1) < 0)
            // swap b[j] and b[j-1]
           for (int k=0; k<sz; k++) {
               char temp = pj[k];
               pj[k] = pj1[k];
               pj1[k] = temp;
           }
     }
}

void print_id(Puser v, int n)
{
  for (int i=0; i<n; i++)
      cout << v[i].name << "\t"
           << v[i].id   << "\t"
           << v[i].dept << "\n";
}
extern int strcmp(char*, char*);

int cmp1(char* p, char* q)
{
  return strcmp(Puser(p)->name, Puser(q)->name);
}

int cmp2(char* p, char* q)
{
  return Puser(p)->dept - Puser(q)->dept;
}

main ()
{
  sort((char*)heads,6,sizeof(user),cmp1);
  print_id(heads,6);
  cout << "\n";
  sort ((char*)heads,6,sizeof(user),cmp2);
  print_id(heads,6);       // in department number order
}





#include <stream.hxx>

class intset {
   int cursize, maxsize;
   int *x;
public:
   intset(int m, int n);
   ~intset();

   int member(int t);
   void insert(int t);

   void iterate(int& i)  { i = 0; }
   int ok(int& i)        { return i<cursize; }
   int next(int& i)      { return x[i++]; }
};

extern void exit (int);

void error(char *s)
{
  cout << "set: " << s << "\n";
  exit(1);
}

extern int atoi(char *);

extern int rand();

int randint (int u)  // in the range 1..u
{
  int r = rand();
  if (r < 0) r = -r;
  return 1 + r%u ;
}

intset::intset(int m, int n)
{
  if (m<1 || n<m) error("illegal intset size");
  cursize = 0;
  maxsize = m;
  x = new int[maxsize];
}

intset::~intset()
{
 delete x;
}

void intset::insert(int t)
{
  if (++cursize > maxsize) error("too many elements");
  int i = cursize-1;
  x[i] = t;

  while (i>0 && x[i-1]>x[i]) {
      int t = x[i];
      x[i] = x[i-1];
      x[i-1] = t;
      i--;
  }
}

int intset::member(int t)
{
  int l = 0;
  int u = cursize-1;

  int m =0;
  while (l <= u) {
      m = (l+u)/2;
      if (t < x[m])
         u = m-1;
      else if (t > x[m])
          l = m+1;
      else
          return 1;    // found
  }
  return 0;    // not found
}

void print_in_order(intset* set)
{
 int var;
 set->iterate(var);
 while (set->ok(var)) cout << set->next(var) << "\n";
}

main (int argc, char *argv[])
{
 if (argc != 3) error("two arguments expected");
 int count = 0;
 int m = atoi(argv[1]);
 int n = atoi (argv[2]);
 intset s(m,n);

 int t = 0;
 while (count <m) {
     t = randint(n);
     if (s.member(t)==0) {
        s.insert(t);
        count++;
    }
 }
 print_in_order(&s);
}




#include <stream.hxx>

struct cl
{
  char* val;
  void print(int x) { cout << val << x << "\n"; }
  cl(char *v) { val = v; }
};


typedef void (cl::*PROC)(int);

main()
{
  cl z1("z1 ");
  cl z2("z2 ");
  PROC pf1 = &cl::print;
  PROC pf2 = &cl::print;
  z1.print(1);
  (z1.*pf1)(2);
  z2.print(3);
  ((&z2)->*pf2)(4);
}




main() {
 char *p = new char[100];
 char *q = new char[100];
 delete p;
 delete p;
}





#include "stream.hxx"

int error (char * p)
{
 cout << p << "\n";
 return 1;
}

class tiny {
  char v;
  tiny assign(int i)
  {  v = (i&~63) ? (error("range error"),0) : i; return *this; }
public:
  tiny (int i)       { assign(i); }
  tiny (tiny& t)      { v = t.v; }
  tiny operator=(tiny& t1) { v = t1.v; return *this; }
  tiny operator=(int i ) { return assign(i); }
  int operator int()         { return v; }
};

void main()
{
 tiny c1 = 2;
 tiny c2 = 62;
 tiny c3 = (c2 - c1);
 tiny c4 = c3;
 int i = (c1 + c2);
 c1 = (c2 + (2 * c1));
 c2 = c1 - i;
 c3 = c2;
}




#include <stream.hxx>

extern int strcpy(char* , char*);

extern int strlen(char *);

struct string {
   char *p;
   int size;
   inline string(int sz) { p = new char[size=sz]; }
   string(char *);
   inline ~string() { delete p; }
   void operator=(string&);
   string(string& );
};

string::string(char* s)
{
 p = new char [size = strlen(s) + 1];
 strcpy (p,s);
}

void string::operator=(string& a)
{
 if (this == &a) return;
 delete p;
 p=new char[size=a.size];
 strcpy(p,a.p);
}


string::string(string& a)
{
 p=new char[size=a.size];
 strcpy(p,a.p);
}
string g(string arg)
{
 return arg;
}

main()
{
 string s = "asdf";
 s = g(s);
 cout << s.p << "\n";
}




#include <stream.hxx>
#include <string.h>
struct pair {
 char * name;
 int val;
};

class assoc {
pair * vec;
int max;
int free;
public:
assoc(int);
int& operator[](char* );
void print_all();
};

assoc::assoc(int s)
{
max = (s<16) ? s: 16;
free = 0;
vec = new pair[max];
}

int& assoc::operator[](char * p)
/*
 maintain a set of "pair"s
 search for p,
 return a reference to the integer part of its "pair"
 make a new "pair" if "p" has not been seen
*/
{
 register pair* pp;
 for (pp=&vec[free-1]; vec<=pp; pp-- )
    if (strcmp(p, pp->name)==0) return pp->val;

 if (free==max) { // overflow: grow the vector
    pair* nvec = new pair[max*2];
    for (int i=0; i<max; i++) nvec[i] = vec[i];
    delete vec;
    vec = nvec;
    max = 2*max;
 }

  pp = &vec[free++];
  pp->name = new char[strlen(p)+1];
  strcpy(pp->name,p);
  pp->val = 0;
  return pp->val;
}

void assoc::print_all()
{
 for (int i=0; i<free; i++)
     cout << vec[i].name << ": " << vec[i].val << "\n";
}

main()
{
 const MAX = 256;
 char buf[MAX];
 assoc vec(512);
 while ( cin>>buf) vec[buf]++;
 vec.print_all();
}





#include <stream.hxx>
#include <string.h>

struct pair {
   char* name;
   int val;
};

class assoc {
friend class assoc_iterator;
   pair* vec;
   int max;
   int free;
public:
   assoc(int);
   int& operator[](char*);
};
class assoc_iterator {
  assoc* cs;
  int i;
public:
  assoc_iterator(assoc& s) { cs = &s; i = 0; }
  pair* operator()()
        { return (i<cs->free)? &cs->vec[i++] : 0; }
};

assoc::assoc(int s)
{
 max = (s<16) ? s : 16;
 free = 0;
 vec = new pair[max];
}

int& assoc::operator[](char* p)
{
 register pair* pp;

 for (pp=&vec[free-1]; vec<=pp; pp-- )
     if (strcmp(p,pp->name)==0) return pp->val;

 if (free ==max) {
    pair* nvec = new pair[max*2];
    for (int i=0; i<max; i++) nvec[i] = vec[i];
    delete vec;
    vec = nvec;
    max = 2*max;
 }

  pp = &vec[free++];
  pp->name = new char[strlen(p)+1];
  strcpy(pp->name,p);
  pp->val = 0;
  return pp->val;
}

main()
{
 const MAX = 256;
 char buf[MAX];
 assoc vec(512);
 while ( cin>>buf) vec[buf]++;
 assoc_iterator next(vec);
 pair* p;
 while (p = next() )
     cout << p->name << ": " << p->val << "\n";
}




#include <stream.hxx>
#include <string.h>

extern void exit(int);
class string {
  struct srep {
       char* s;
       int n;
  };
  srep *p;

public:
  string(char *);
  string();
  string(string &);
  string& operator=(char *);
  string& operator=(string &);
  ~string();
  char& operator[](int i);

  friend ostream& operator<<(ostream&, string&);
  friend istream& operator>> (istream&, string&);

  friend int operator==(string &x, char *s)
      { return strcmp(x.p->s, s) == 0; }

   friend int operator==(string &x, string &y)
      { return strcmp(x.p->s, y.p->s) == 0; }

   friend int operator!=(string &x, char *s)
      { return strcmp(x.p->s, s) != 0; }

   friend int operator!=(string &x, string &y)
      { return strcmp (x.p->s, y.p->s) != 0; }
};

string::string()
{
  p = new srep;
  p->s = 0;
  p->n = 1;
}

string::string(char* s)
{
 p = new srep;
 p->s = new char[ strlen(s) +1];
 strcpy(p->s, s);
 p->n = 1;
}
string::string(string& x)
{
 x.p->n++;
 p = x.p;
}

string::~string()
{
 if (--p->n == 0){
    delete p->s;
    delete p;
 }
}

string& string::operator=(char* s)
{
 if (p->n > 1) {
    p->n--;
    p = new srep;
 }
 else if (p->n == 1)
    delete p->s;

 p->s = new char[ strlen(s)+1 ];
 strcpy(p->s, s);
 p->n = 1;
 return *this;
}

string& string::operator=(string& x)
{
 x.p->n++;
 if (--p->n == 0) {
    delete p->s;
    delete p;
 }
 p = x.p;
 return *this;
}

ostream& operator<<(ostream& s, string& x)
{
  return s << x.p->s << " [" << x.p->n << "]\n";
}

istream& operator>>(istream& s, string& x)
{
 char buf[256];
 s>>buf;
 x = buf;
 cout << "echo: " << x << "\n";
 return s;
}

void error(char* p)
{
 cout << p << "\n";
 exit(1);
}
char& string::operator[](int i)
{
 if (i<0 || strlen(p->s)<i) error("index out of range");
 return p->s[i];
}

main()
{
  string x[100];
  int n;

  cout << "here we go\n";
  for (n = 0; cin>>x[n]; n++) {
      string y;
      if (n==100) error("too many strings");
      cout << (y = x[n]);
      if (y=="done") break;
  }
  cout << "here we go back again\n";
  for (int i=n-1; 0<=i; i--) cout << x[i];
}




#include <stream.hxx>

struct employee {
friend class manager;
   employee* next;
   char*     name;
   short     department;
   virtual void print();
};

struct manager : employee {
   employee* group;
   short     level;
   void print();
};

void employee::print()
{
 cout << name << "\t" << department << "\n";
}

void manager::print()
{
  employee::print();
  cout << "\tlevel " << level << "\n";
}

void f(employee* ll)
{
 for ( ; ll; ll=ll->next) ll->print();
}

main ()
{
  employee e;
      e.name = "J. Brown";
      e.department = 1234;
      e.next = 0;
   manager m;
      m.name = "J. Smith";
      m.department = 1234;
      m.level = 2;
      m.next = &e;
f(&m);
}





#include <stream.hxx>

struct base { base(); };

struct derived : base { derived(); };

base:: base()
{
 cout << "\tbase 1: this=" << long(this) << "\n";
 if (this == 0) this = (base*)27;
 cout << "\tbase 2: this=" << long(this) << "\n";
}

derived::derived()
{
 cout << "\tderived 1: this=" << long(this) << "\n";
 if (this == 0) this = (derived*)43;
 cout << "\tderived 2: this=" << long(this) << "\n";
}

main()
{
 cout << "base b;\n";
 base b;
 cout << "new base;\n";
 new base;
 cout  << "derived  d;\n";
 derived d;
 cout << "new derived;\n";
 new derived;
 cout << "new derived;\n";
 new derived;
 cout << "at the end\n";
}





#include <xstream.hxx>

extern void exit(int);

void error(char* s, char* s2)
{
 cerr << s << " " << s2 << "\n";
 exit(1);
}

main(int argc, char* argv[])
{
 if (argc != 3) error ("wrong number of arguments","");

 filebuf f1;
 if (f1.open(argv[1],input) == 0)
    error("cannot open input file",argv[1]);
 istream from(&f1);

 filebuf f2;
 if (f2.open(argv[2],output) == 0)
    error("cannot open input file",argv[2]);
 ostream to(&f2);

 char ch;
 while (from.get(ch)) to.put(ch);

 if (!from.eof() || to.bad())
    error("something strange happened","");
}




Last-modified: Wed, 08 May 2002 14:07:44 GMT
Ocenite etot tekst: