Programmer’s Reference


ГЛАВА 5 – Справочник на ключовите думи



страница6/19
Дата21.09.2016
Размер2.35 Mb.
#10416
1   2   3   4   5   6   7   8   9   ...   19

ГЛАВА 5 – Справочник на ключовите думи

Езика С дефинира следните 32 ключови думи :



auto double int struct

break else long switch

case enum register typedef

char extern return union

const float short unsigned

continue for signed void

default goto sizeof volatile

do if static while

С++ включва всички ключови думи дефинирани от С и добавя следните :

asm inline template

bool mutable this

catch namespace throw

class new true

const_cast operator try

delete private typeid

dynamic_cast protected typename

explicit public using

false reinterpret_cast virtual

friend static_cast wchar_t

По – старите версии на С++ също дефинираха ключовата дума overload но тя е излязла от употереба .Всички ключови думи са със малки букви . Следва кратко описание на всяка от ключовите думи :


аsm


Asm се използва да вгради асемблерен език директно във вашата С++ програма . Общата форма на asm израза е :

аsm (“ инструкция “ ) ;

Тук инструкция е инструкция на асемблерен език , която се подава директно на компилатора за вграждане във програмата . Много С++ компилатори позволяват допълнителни форми на израза asm . Например Borland C++ позволява следните asm изрази :

аsm инструкция ;

asm {

последователност от инструкции

}

Тук последователност от инструкции е списък със асемблерни инструкции .

Забележка : Microsoft Visual C++ използва ­­__asm за вграждане на асемблерен код . Той иначе е подобен на asm .


auto



auto декларира локална променлива . Тя е напълно незадължителна и рядко използвана .

bool




Спецификатора за тип bool се използва за деклариране на булеви ( тоест true (false ) ) стойности .

break



break се използва за изход от do , for или while цикъл прескачайки нормалното условие на цикъла . Тя също се използва за изход от израза switch . Пример за break във цикъл е показан тук :

do {



x = getx ( ) ;

if ( x < 0 ) break ; //прекъсва if ако е отрицателно

process (x) ;



} while (!done ) ;

Тук ако х е отрицателно , цикъла се прекъсва . Във израз switch , break предпазва програмата от влизане във следващия case ( Вижте “switch “ за подробности ). Break прекъсва само for , do , while или switch които го съдържат . Той няма да прекъсне никой вложен цикъл или switch израз .


case

Израза case се използва със израза switch . Виж “ switch “ .


catch

Израза catch манипулира изключение генерирано от throw . Виж “throw “ .


char



char е тип данни използван за деклариране на символни променливи .

class



class се използва за деклариране на класове – основната част в С++ за капсулиране . Неговата обща форма е :

class име_на_клас : списък с наследявания {

// private членове по подразбиране

protected :

// private членове които могат да се наследяват

public :



// public членове

} списък със обекти ;

Тук име_на_клас е името на новия тип данни който се генерира от декларацията class . Списъка с наследявания който е незадължителен , определя всички базови класове наследени от новия клас . По подразбиране , членовете на class са private . Те могат да станат protected или public чрез използване на ключовите думи protected и public , съответно . Списък с обекти е опционен . Ако не е представен , декларацията просто определя форма на клас . Тя не създава никакви обекти от класа .

Забележка : За допълнителна информация вижте Глава 1

const

Модификатора const казва на компилатора че променливата не може да бъде променяна от програмата . const променлива може обаче да взима инициализираща стойност когато се декларира .


const_cast

Оператора const_cast се използва да предефинира явно const и/или volatile при преаобразуване . Той има тази форма :

const_cast < тип > (обект )

Целевия тип трябва да бъде еднакъв като изходния тип с изключение на променянето на неговите const или volatile атрибути . Най – честата употреба на const_cast е да премахва константността (const ) .



continue



continue се използва да прескочи часта от кода във цикъл и да предизвика условния израз да бъде изчислен . Например следващия цикъл while просто ще чете символи от клавиатурата докато не се въведе s :

while ( ch = getchar ( ) ) {

if ( ch != ‘s ‘ ) continue ; // чете друг знак

process ( ch ) ;



}

Извикването на process ( ) няма да стане докато ch не съдържа символа s .



default



default се използва във израза switch да означи подразбиращ се блок от код който да бъде изпълнен ако няма съвпадения открити във switch ( Виж

switch “ )


delete

Оператора delete освобождава паметта указвана от неговия аргумент . Тази памет трябва да бъде заделена преди това от new . Формата на delete e :



delete p_var ;

където p_var е указател към преди това заделена памет . За освобождаване на масив който е бил заделен чрез new използвайте тази форма на delete :



delete [ ] p_var ;

do

Цикъла do е един от трите конструкции за цикъл налични във С++ .Общата форма на цикъла е :

do {

блок от изрази

} while ( условие ) ;

Ако само един израз се повтаря скобите не са необходими , но те добавят яснота на израза . Цикъла do е единствения цикъл в С++ който винаги ще има поне една итерация понеже условието се проверява на края на цикъла .

double



double е спецификатор за тип данни използван за деклариране на променлива със плаваща точка със двойна точност.

dynamic_cast



dynamic_cast изпълнява преобразуване по време на изпълнение (runtime ) което проверява валидността на преобразуването . Има тази обща форма :

dynamic_cast < тип > (обект )

Главната употреба на dynamic_cast e да изпълни преобразуване на полиморфни типове . Например , имайки два полиморфни класа B и D , и D е производен от B , dynamic_cast може винаги да преобразува D* указател във B* указател . dynamic_cast може да преобразува B* указател във D* указател само ако обекта който ще се указва е в действителност D* . Въобще dynamic_cast ще успее ако опитаното полиморфно преобразуване е позволено ( тоест ако целевия тип може легално да бъде прибавен към типа от обекта който се преобразува ) . Ако преобразуването се осъществи тогава dynamic_cast се изчислява на 0 .

else

Виж “ if “.



enum

Спецификатора за тип enum се използва да създаде изброителни типове . Изброяването е просто списък от именовани целочислени константи . Общата форма на изброяване е :

enum име { списък- с – имена } списък – с – променливи ;

Име е името на типа изброяване . Списък – с – променливи е опционен и изброителните променливи могат да бъдат декларирани отделно от дефиницията на типа , както показва следващия пример . Този код декларира изброяване наречено color и променлива от този тип наречена c и тя изпълнява присвояване и условна проверка :

enum color { red , green , yellow } c ;



c = red ;

if ( c == red ) cout << “ is red \n “ ;

Забележка : За повече подробности за изброяванията се обърнете към Глава 1 .

explicit

Спецификатора explicit се прилага само за конструкторите . Конструктор определен като explicit ще може да бъде използван само когато инициализацията точно съответства на определената чрез конструктора . Никакво автоматично преобразуване не се извършва ( създава се “ непреобразуващ конструктор “ )



extern



extern е модификатор за типове данни който казва на компилатора за променлива която е дефинирана някъде на друго място в програмата . Това е често използвано при свързването със отделно компилирани файлове които поделят еднакви глобални данни и се свързват заедно . Всъщност тя информира компилатора за типа на променливата без да я предефинира . Например ако first беше дефинирана във друг файл като цяло число , тази декларация ще бъде използвана във други файлове :

extern int first ;

Тази декларация определя типа на first , но не заделя място за съхранението й . В С++ extern се използва за създаване на свързваща спецификация . Тя има тази форма :

extern език “ прототип-на-функция

Тук език определя езика в който искате да се свърже функцията . С и С++ свързването са гарантирано поддържани . Вашия компилатор може също да поддържа и други свързвания . За да декларирате няколко функции използвайки еднаква свързваща спецификация използвайте тази обща форма :

extern език “ {



прототипи- на – функции

}

false



false е булева константа за false .

float



float e спецификатор за тип данни използван за даклариране на променливи със плаваща точка .

for

Цикъла for автоматично инициализира и инкрементира променлива- брояч . Формата му е :

for ( инициализация ; условие ; инкрементиране ) {

блок- със – изрази

}

Ако блок- със – изрази е само един израз скобите не са необходими . Макар че for позволява няколко варианта , най- общо инициализация установява променлива за контрол на цикъла в начална стойност . Условие е обикновенно релационен израз който проверява контролната променлива със прекъсваща стойност , и инкрементиране я увеличава ( или намалява ) .Ако условие е false във началото , тялото на цикъла for няма да се изпълни нито веднъж . Следващия израз ще отпечати съобщенито “hello “ 10 пъти :

for (t = 0 ; t<10 ; t ++) cout << “ hello \n “ ;

friend

Ключовата дума friend разрешава не – член функция да има достъп до private членовете на клас . За да направите friend функция , включете нейния прототип във public секцията на декларацията на класа и сложете пред нейния прототип думата friend . Например в следващия клас myfunc ( ) e friend и не е член на myclass :



class myclass {

// . . .

public :

friend void myfunc ( int a , float b ) ;

// . . .

} ;

Запомнете че friend функцията няма this указател понеже не е член на класа .


goto

Ключовата дума goto предизвиква изпълнението на програмата да прескочи до етикет определен във израза goto . Формата на goto e :



goto етикет ;

.

.

.

етикет :

Всички етикети трябва да завършват със двоеточие и не трябва да влизат във конфликт със ключови думи или имена на функции . Освен това goto може само да прескача във текущата функция , а не от една функция към друга.



Програмен съвет

Макар че goto беше изхвърлен от употреба преди десетилетия като метод за програмен контрол , понякога има употреба . Едно от приложенията му е като начин за изход от дълбоко вложени цикли . Например разгледайте този фрагмент :

int i , j , k ;

int stop = 0 ;

for ( i = 0 ; i < 100 && !stop ; i++ ) {

for ( j = 0 ; j < 10 && !stop ; j++ ) {

for ( k = 0 ; k < 20 ; k++ ) {

// . . .

if ( something ( ) ) {

stop = 1 ;

break ;

}

}

}

}

Както можете да видите променливата stop се използва за отказ от два външни цикъла ако се случи някакво програмно събитие . Обаче по – добър начин да изпълните това е показан тук чрез използване на goto :



int i , j , k ;

for ( I = 0 ; I < 100 ; I++ ) {

for ( j = 0 ; j < 10 ; j++ ) {

for ( k = 0 ; k < 20 ; k++ ) {

// . . .

if ( something ( ) ) {

goto done ;

}

}

}

}

done : // . . .

Както можете да видите , употребата на goto елиминира свръхпретрупването което се получава чрез добавянето на повтарящи се проверки на stop във предишната версия . Докато употребата на goto като форма със общо предназначение за контрол на цикъл трябва да бъде избягвано , понякога може да бъде ангажирана със голям успех .


if

Ключовата дума if позволява посоката на действието да бъде определена от резултата от условие . Формата на израза if e :



if ( условие ) {

блок – с – изрази 1

}

else {

блок – с – изрази 2

}

Ако се използват единични изрази , скобите не са необходими . else е незадължително . Условието може да бъде всякакъв израз . Ако се изчислява на true ( всяка стойност различна от 0 ) тогава блок – с – изрази 1 ще се изпълни , в противен случай ще се изпълни блок – с – изрази 2 . Следващия фрагмент проверява дали x е по – голямо от 10 :

if ( x > 10 )

cout << “ x is greater than 10 . “ ;

else

cout << “x is less than or equal to 10 . “ ;

inline

Спецификатора inline казва на компилатора да разшири кода на функцията отколкото да я извиква . Спецификатора inline е заявка а не команда , понеже различни фактори могат да попречат кода да бъде разширен . Някой общи ограничения като например рекурсивни функции , функции съдържащи цикъл или switch изрази и функции съдържащи static данни . Спецификатора inline предхожда останалата част от декларацията на фукцията . Следващия фрагмент казва на компилатора да генерира inline код за myfunc ( ) :



inline void myfunc ( int I )

{

// . . .

}

Когато дефиницията е включена във декларацията на клас , тогава кода автоматично се разглежда като inline ако е възможно .



int



int е спецификатор за тип използван за деклариране на целочислени променливи .

long



long е модификатор на типове данни използван за деклариране на дълги целочислени променливи .

mutable

Спецификатора mutable позволява на член на обект да предефинира константността ( const ) .Така mutable член на const обект не е const и може да бъде изменен . Главната употреба на mutable е за позволяване на const член – функция да изменя избрани членове данни .


namespace


Ключовата дума namespace ви позволява да разделите глобалното именовано пространство чрез създаване на декларативен регион . Всъщност именованото пространство определя интервал . Общата форма на namespace e :



namespace име {

// декларации

}

В добавка може да имате безименно именовано пространство както е показано тук :

namespace {

// декларации

}

Безименното именовано пространство ви позволява да създадете уникални идентификатори които са познати само в обхвата на единствен файл . Тук е пример за namespace :



namespace MyNameSpace {

int i , k ;

void myfunc ( int j ) { cout << j ; }

}

Тук i , k и myfunc ( ) са част от интервал определен от именованото пространство MyNameSpace . Понеже namespace дефинира интервал , трябва да използвате оператора за разрешаване на интервал за достъп до обекти дефинирани в него . Например за присвояване на стойност 10 на i , трябва да използвате този израз :

MyNameSpace :: i = 10 ;

Ако членовете на именовано пространство ще бъдат често използвани , може да използвате директива using за опростяване на достъпа до тях . Израза using има тези две форми :

using namespace име ;

using име :: член ;

В първата форма , име определя името на именованото пространство до което искате достъп . Всички членове във определеното именовано пространство могат да бъдат достъпвани директно . Във втората форма само определен член на именованото пространство се прави видим . Например приемайки MyNameSpace както е показано по – горе следващите using изрази и присвоявания са валидни :

using MyNameSpace :: k ; // само к се прави видим

k = 10 ; // OK понеже к е видим

using namespace MyNameSpace ;

// всички членове на MyNameSpace са видими

i = 10 ;

// ОК понеже сега са видими всички членове на MyNameSpace

new

Оператора new заделя динамично памет и връща указател от съответния тип към нея . Общата му форма е :

p_var = new тип ;

Тук p_var е указателна променлива която получава адреса на заделената памет , а тип е типа данни които че се съхранява паметта . Оператора new автоматично заделя достатъчно памет за съхранението на данни от определения тип . Например следващия фрагмент заделя достатъчно памет за съхранение на double :



double *p_var ;

p = new double ;

Ако зявката за заделяне пропадне , ще се случи едно от тези две събития : или ще се върне нулев указател или ще се предизвика изключение bad_alloc (понастоящем някой компилатори извеждат изключение xalloc ).



Забележка : По време на написването на това точното държане на new при грешка е вече определено . Различните компилатори изпълняват различни действия при грешка в заделянето . Проверете документацията на компилатора за информация за сегашната ви работна среда . Можете да инициализирате заделената памет чрез определянето на инициализатор използвайки тази форма :

p_var = new тип ( инициализатор ) ;

Тук инициализатор е стойността която ще бъде присвоена на заделената памет . За заделяне на едномеран масив използвайте тази форма :

p_var = new тип [ размер ] ;

Тук размер определя дължината на масива . new автоматично ще задели достатъчно място за съхранение на масива от определения тип и големина . Когато заделяте динамично масиви не можете да ги инициализирате .

operator

Ключовата дума operator се използва за създаване на предефинирана функция оператор . Операторните функции имат две разновидности : член и нечлен . Общата форма на операторна член функция е :

връщан- тип име_на_клас :: operator# (списък- с – параметри ) {

// . . .

}

Тук връщан – тип е връщания от функцията тип , име_на_клас е името на класа за който се предефинира оператора и # е оператора който се предефинира . Когато предефинирате унарен оператор , списък – с – параметри е празен ( оператора е подаден косвено в this ) Когато предефинирате бинарен оператор списък – с – параметри определя операнда от дясната страна на оператора (оператора от лявата страна е подаден косвено в this ) За нечлен функции , операторната функция има тази обща форма :

връщан – тип operator# ( списък – с – параметри ) {

// . . .

}

Тук списък- с – параметри съдържа един параметър когато предефинираме унарен оператор и два параметъра когато предефинираме бинарен оператор . Когато предефинираме бинарен оператор операнда отляво е подаден в първия параметър , а операнда отдясно е подаден в десния параметър . Има няколко ограничения към предефинирането на оператори . Първо не можете да промените приоритета на оператора , не може да промените броя на операндите на оператора , не може да промените значението на оператор отнасящ се до вградените в С++ типове данни , не може да създадете нов оператор . Предпроцесорните оператори # и ## не могат да се предефинират . Не могат да се предефинират и следните оператори : . : .* ?


private

Спецификатора за достъп private декларира private членове на клас . Той също се използва за частично наследяване на базов клас . Когато се използва за деклариране на private членове има тази форма :

class име_на_клас {

// . . .

private :

// private членове

} ;

Членовете на клас са private по подразбиране . Така спецификатора само ще се използва във декларацията на клас за започване на друг блок от private декларации . Например това е валидна декларация на клас :

class myclass {

int a , b ; // private по подразбиране

public :



int x , y ; // тези са public

private :



int c , d ; // тези са private

} ;

Когато се използва като спецификатор при наследяване private има тази форма :

class :: име_на_клас : private базов – клас { // . . .

Чрез определяне на базов – клас като private всички public и protected членове на базовия клас стават private членове на производния клас . Всички private членове на базовия клас остават private за него .

protected

Спецификатора за достъп protected декларира членове на клас които са private за класа но могат да се наследяват от всеки производен клас . Има тази форма :

class име_на_клас {

// . . .

protected : // прави ги protected

// protected членове

} ;

Например :

class base {

// . . .

protected :

int a ;

// . . .

} ;

// сега наследява base в derived клас

class derived : public base {

// . . .

public ;

// . . .

// derived има достъп до а

void f ( ) { cout << a ; }



} ;

Тук а е private за base и не е достъпна никоя нечлен функция . Обаче , derived наследява достъп към а . Ако а беше просто дефинирана като private , derived нямаше да има достъп до нея . Когато се използва като спецификатор при наследяване protected има тази форма :

class :: име_на_клас : protected базов – клас { // . . .

Чрез определяне на базовия клас като protected , всички public и protected членове на базовия клас стават protected членове на производния клас , а във всички случай private членовете на базовия клас остават private за базовия .


public

Спецификатора за достъп public декларира public членове на клас . Той също се използва за публично наследяване на базов клас . Когато се използва за деклариране на public членове има тази форма :

class име_на_клас {

// private членове по подразбиране

public : // прави ги public

// public членове

} ;

Членовете на клас са private по подразбиране . За да декларирате public членове трябва да ги определите като public . Когато се използва като спецификатор при наследяване , public има тази форма :

class :: име_на_клас : public базов – клас { // . . .

Чрез определянето на базовия клас като public , всички public членове на базовия клас стават public членове на производния клас и всички protected членове на базовия клас стават protected членове на производния клас . Във всички случай , private членовете на базовия клас остават private за базовия .


register

Модификатора за съхраняване на клас register заявява че достъпа към променлива ще бъде оптимизиран по скорост . Традиционно register се прилага само към integer и символни променливи , предизвиквайки да бъдат съхранявани във регистрите на CPU вместо да се поставят в паметта . Значението на register беше разширено да включва всички типове данни . Обаче други данни освен integer и символи не могат обикновенно да се съхраняват в регистрите на CPU . За другите типове данни се използва или кеш паметта (или някакъв друг тип оптимизационна схема ) , или register заявката се отхвърля . register може да бъде използван само за локални променливи . В С не можете да вземете адреса на register променлива . Обаче в С++ можете ( макар че правейки това можете да попречите променливата да бъде оптимизирана ) .


reinterpret_cast

Оператора reinterpret_cast променя един тип във фундаментално различен тип . Например той може да се използва да промени указател във integer . Има тази обща форма :

reinterpret_cast < тип > ( обект )

reinterpret_­cast може да бъде използван за преобразуване на напълно несъвместими указателни типове .

return

Израза return предизвиква връщане от функция и може да бъде използван за прехвърляне на стойност към извикващия процес . Има тези две форми :

return ;

return стойност ;

В С++ , формата която не определя стойност трябва да бъде използвана само във void функции . Следващата функция връща резултата от нейните два целочислени аргумента :

int mul ( int a , int b )

{

return a*b ;

}

Запомнете че когато се срещне return , функцията са връща прескачайки всеки друг код който може да има във нея. Също функция може да има повече от един return израз .


short




short е модификатор за тип данни използван за деклариране на къси цели числа .

signed

Главната употреба на модификатора за тип signed е за определяне на тип данни signed char . Неговата употреба във други типове е излишна понеже целите числа са със знак по подразбиране .


sizeof

Оператора по време на компилация sizeof връща дължината ( в байтове ) на променливата или типа който предхожда .Ако е поставен пред тип тогава типа трябва да бъде заграден в скоби . Ако е пред променлива ограждането е незадължително . Например имайки :

int i ;

cout << sizeof ( int ) ;

cout << sizeof i ;

и двата израза ще изведат 4 за повечето 32 – битови С++ компилатори .


static



static е модификатор за тип данни който създава постоянно съхраняване за локална променлива която предхожда . Това позволява определената променлива да поддържа стойноста си между извикванията на функция . static може също да бъде използван за деклариране на глобални променливи . В този случай тя ограничава интервала на променливата която модифицира само до файла в който тя е декларирана . В С++ когато static се използва върху член променливи на клас , тя предизвиква само едно копие от този член да бъде поделяно от всички обекти от този клас .

static_cast

Оператора static_cast изпълнява полиморфно преобразуване .Например може да бъде използван за преобразуване на указател към базов клас във указател към производен клас .Той също може да бъде използван за всякакво стандартно превръщане . Никакви runtime проверки не се извършват . Има тази обща форма :

static_cast < тип > ( обект )

struct

Ключовата дума struct се използва за създаване на агрегатен тип данни наречен структура . В С++ структурата може да съдържа и функции и данни . В С++ структурата има еднакви свойства като class с изключение на това че по подразбиране нейните членове са public вместо private . Общата форма на С++ структура е:

struct име_на_клас : списък – с – наследявания {

// public членове по подразбиране

protected :

// private членове които могат да се наследяват

private :

// private членове

} списък от обекти ;

Име_на_клас е името на типа структура която е тип клас . Отделните членове се достигат чрез използване на точка когато оперираме със структура или чрез използване на оператор стрелка когато оперирате чрез указател към структура . Списък- с- наследявания и списък от обекти са незадължителни . В С структурите могат да съдържат само член променливи , private и protected спецификаторите не са разрешени и няма списък с наследявания . Следващата структура в С-стил съдържа низ наречен name и две integer наречени high и low . Тя също декларира една променлива наречена my_var :

struct my_struct {

char name [80] ;

int high ;

int low ;

} my_var ;

Забележка : Виж Глава 1 за повече детайли за структурите .

switch

Израза switch е многократно разклоняващ израз в С/С++ . Той се използва да насочи изпълнението в един от няколко различни пътя . Общата форма на израза е :

switch ( израз ) {

case константа 1 : последователност – от – изрази 1 ;

break ;

case константа 2 : последователност – от – изрази 2 ;

break ;



.

.

.

case константа N : последователност – от – изрази N ;

break ;



default : изрази- по – подразбиране ;

}

Всяка последователност от изрази може да бъде от един или няколко израза . Частта default е опционна . И двете израз и case константи трябва да са целочислени типове . switch работи чрез проверяване на израз със константи . Ако е открито съвпадение се изпълнява тази последователност . Ако последователността от изрази свързани със съвпадащото case не съдържа break , изпълнението ще продължи във следващия case . Казано различно , от точката на съвпадение , изпълнението ще продължи докато или не се срещне израз break или switch не завърши . Ако няма съвпадение и случая default съществува , се изпълнява неговата последователност от изрази . В противен случай не се изпълнява нищо . Следващия пример обработва избор от меню :

switch ( ch ) {



case ‘e’ : enter ( ) ;

break ;

case ‘l’ : list ( ) ;

break ;

case ‘s’ : sort ( ) ;

break ;

case ‘e’ : enter ( ) ;

break ;

case ‘q’ : exit (0) ;

break ;

default :

cout << “Unknown command! \n “ ;

cout << Try again. \n “ ;

}

template

Ключовата дума template се използва за създаване на шаблонни функции и класове . Типа данни опериращи със шаблонната функция или клас е определен като параметър . Така една функция или дефиниция на клас може да бъде използвана със няколко различни типове данни . Следват детайлите отнасящи се до шаблонните функции и класове . Шаблонната функция дефинира общо множество от операции което може да бъде приложено към различни типове данни . Шаблонната функция има тип данни с които ще оперира подаден като параметър . Използвайки този механизъм еднаква обща процедура може да бъде приложена към широк кръг данни . Както знаете много алгоритми са логически еднакви независимо от типа данни които обработват . Например алгоритъма Quicksort е еднакъв независимо дали е приложен към масив от integer или масив от числа със плаваща точка . Само типа данни които ще се сортират е различен . Чрез създаване на шаблонна функция може да дефинирате независимо от никакви данни естеството на алгоритъма . След като го направите , компилатора автоматично генерира правилния код за реално използваните данни когато изпълнявате функцията . Всъщност когато създавате шаблонна функция вие създавате функция която може автоматично да се предефинира . Общата форма на дефиниция на шаблонна функция е :



template < class тип- данни > връщан – тип име_на_функция (списък с параметри )

{

// тяло на функцията

}

Тук тип – данни е мястото за съхраняване на типа данни върху които в действителност ще оперира функцията . Следващата програма създава шаблонна функция която разменя стойностите на две променливи . Понеже процеса по размяната на две стойности не зависи от типа на променливите , тя е добър кандидат да бъде направена шаблонна функция :

// пример за шаблонна функция

#include < iostream >



using namespace std ;

template < class X > void swapvals ( X &a , X &b )

{

X temp ;

temp = a ;

a = b ;

b = temp ;

}

int main ( )

{

int i = 10 , j = 20 ;

float x = 10.1 , y = 23.3 ;

cout << “ Original i , j : “ << i << ‘ ‘ << j << endl ;

cout << “ Original x , y : “ << x << ‘ ‘ << y << endl ;

swapvals ( i , j ) ; // разменя integer

swapvals ( x , y ) ; // разменя float

cout << “ Swapped i , j : “ << i << ‘ ‘ << j << endl ;

cout << “ Swapped x , y : “ << x << ‘ ‘ << y << endl ;

return 0 ;

}

В тази програма реда :

template < class X > void swapvals ( X &a , X &b )

казва на компилатора две неща : първо че е създадена шаблонна функция и второ че X е шаблонен тип който се използва като място за съхранение . Тялото на swapvals ( ) е дефинирано чрез използване на X като тип данни за стойностите които ще се разменят . В main ( ) функцията swapvals ( ) се извиква използвайки два различни типа данни : integer и числа с плаваща точка . Понеже swapvals ( ) е шаблонна функция компилатора автоматично създава две версии на swapvals ( ) – една която разменя integer и една която разменя float . Можете да дефинирате повече от един шаблонен тип използвайки в израза template списък разделен със запетайки . Шаблонните функции са подобни на предефинираните функции с изключение на това че са по ограничаващи . Когато се предефинира функция , можете да имате различни действия изпълнявани от тялото на всяка функция . Шаблонната функция трябва да изпълнява едно и също действие във всички версии . В добавка към шаблонните функции можете да дефинирате шаблонен клас . Когато правите това вие създавате клас който дефинира всички алгоритми използвани от този клас , но дейзтвителния тип манипулационни данни ще бъде определен като параметър когато се създават обекти от този клас . Шаблонните функции са полезни когато класа съдържа обобщаваща логика . Например един алгоритъм който поддържа опашка от integer ще работи също със опашка от символи . Също механизма който управлява свързан списък от пощенски адреси може да управлява списък от авточасти . Чрез използване на шаблонен клас можете да създадете клас който ще поддържа опашка , свързан списък и множество други типове данни . Компилатора ще генерира автоматично правилния тип обект базирайки се на типа който сте определили когато се създава обекта . Общата форма на декларация на общ клас е :

template тип- данни > class име_на_клас {

// . . .

} ;

В този случай , тип данни е мястото за съхранение на типа данни със които ще оперира класа . Когато декларирате обект от шаблонен клас вие определяте типа данни между ъглови скоби използвайки тази обща форма :



име_на_клас < тип > обект ;

Следващия пример е шаблонен клас . Тази програма създава много прост клас за едностранно свързан списък . След това демонстрира класа чрез създаване на свързан списък който съхранява символи :

// прост шаблонен свързан списък

#include < iostream >



using namespace std ;

template < class data_t > class list {

data_t data ;

list *next ;

public :

list (data_t d ) ;

void add ( list *node ) { node-> next = this ; next = 0 ; }

list *getnext ( ) { return next ; }

data_t getdata ( ) { return data ; }

} ;

template

list < data_t > :: list ( data_t d )

{

data = d ;

next = 0 ;

}

int main ( )

{

list < char > start ( ‘a’ ) ;

list *p , *last ;

int i ;

// изгражда списък

last = &start ;

for (i = 0 ;i < 26 ; i++ ) {

p = new list (‘a’ +I ) ;

p -> add ( last ) ;

last = p ;

}

// следва списъка

p = &start ;

while (p) {

cout << p->getdata ( ) ;

p = p ->getnext ( ) ;

}

return 0 ;

}

Както можете да видите декларацията на шаблонния клас е подобна на декларацията на шаблонна функция . Типа данни съхранявани от списъка е направен общ в декларацията на класа . В main ( ) обектите и указателите са създадени така че типа данни във списъка да бъде char . Списъци от други типове също може да бъде създаден . Обърнете специално внимание на тази декларация :

list < char > start (‘a’ ) ;

Забележете как желания тип данни е подаден вътре в ъглови скоби .




this



this е указател към обекта който генерира извикването към член функция . На всички член функции автоматично се подава this указател .

throw



throw е част от подсистемата на С++ за обработване на изключения . Следва описание . Обработката на изключения е изградена от три ключови думи : try , catch и throw . В повечето случай , програмните изрази които искате да наблюдавате за изключения се съдържат в блок try . Ако изключение ( грешка ) стане във try блок , то се прехвърля (чрез throw ) . Изключението се прихваща чрез catch и се обработва . Следното описание доказва това . Както беше казано всеки израз който предизвиква изключение трябва да бъде изпълнен вътре във блок try блок ( функциите извикани от try блок могат също да прехвърлят изключение ) Всяко изключение трябва да бъде прихванато чрез catch израз който следва непосредствено израза try който прехвърля изключението . Общата форма на try и catch е :

try {

// блок try

}

catch ( тип1 аргумент ) {

// блок catch

}

catch ( тип2 аргумент ) {

// блок catch

}

catch ( тип3 аргумент ) {

// блок catch

}

// . . .

catch ( типN аргумент ) {

// блок catch



}

Блока try трябва да съдържа частта от вашата програма която искате да наблюдавате за грешки . Това може да са няколко израза в една функция или пълно заграждане на функцията main ( ) във try блок ( което означава да бъде наблюдавана цялата програма ) Когато се предизвика изключение , то се прихваща чрез съответния му израз catch който го обработва . Може да има повече от един catch израз свързан със try блока . Кой catch израз ще се използва се определя от типа на изключението . Така ако типа данни определен от catch съответства на изключението , тогава този catch израз се изпълнява ( всички други се пропускат ) Когато се прихване изключение аргумент ще получи неговата стойност . Всеки тип данни може да бъде прихванат включително и класовете които създавате . Ако не се предизвика изключение ( тоест не са се случили грешки във try блока ) , тогава никой catch израз не се изпълнява . Формата на израза throw e :



throw изключение ;

throw трябва да бъде изпълнен или във самия блок try или от извиквана отвътре на блока try функция (директно или индиректно ) Изключение е прехвърляната стойност . Ако предизвикате изключение за което няма приложен catch израз може да стане ненормално приключване на програмата . Предизвикването на необработвани изключения причинява извикването на функцията terminate ( ) . По подразбиране terminate ( ) извиква abort ( ) за спиране на програмата . Обаче можете да определите собствени манипулатори ако искате , използвайки set_terminate ( ) .Тук е показан прост пример за начина на обработка на изключения в С++ :

// пример за просто манипулиране на изключения

#include < iostream .h >

using namespace std ;

int main ( )

{

cout << “Start \n “ ;

try { // стартира try блок

cout << ”Inside try block \n “ ;



throw 100 ; // прехвърля грешка

cout << “ This will not execute “ ;



}

catch ( int i ) { // прехваща грешка

cout << “Caught an exception – value is : “ ;



cout << i << “ \n “ ;

}

cout << “ End “ ;

return 0 ;

}

Тази програма извежда следния резултат :

Start
Inside try block


Caught an exception – value is : 100

End

Както можете да видите , във try блока има три израза и catch ( int i ) обработва integer изключение . Във try блока , само два от трите израза ще се изпълнят : първия cout израз и throw . Когато се предизвика изключение контрола преминава към catch израза и try блока се прекъсва . Тоест catch не се извиква . По скоро програмата се прехвърля към него ( програмния стек автоматично установява кога трябва да се изпълни това ) Така cout израза след throw никога няма да се изпълни .


true



true е булева константа за true .

try



try е част от механизма на С++ за обработка на изключения (виж throw )

typedef

Ключовата дума typedef ви позволява да създавате ново име за съществуващ тип данни . Типа данни може да бъде или един от вградените типове или клас , структура , обединение или изброяване . Формата на typedef e :



тypedef спецификатор- на – тип ново – име ;

Например , за да използвате думата balance на мястото на float трябва да напишете :

typedef float balance ;

typeid

В С++ оператора typeid връща референция към type_info обект който описва типа на обекта на който е приложен typeid . typeid има тази обща форма :

тypeid ( обект )

typeid поддържа идентификация по време на изпълнение ( RTTI ) в С++ .

Забележка : Виж “ typeid “ в Глава 3 .

typename

С++ поддържа ключовата дума typename .Тя може да бъде използвана на мястото на ключовата дума class във template декларация или за означаване на неопределен тип .


union



union е специален тип клас който слага две или повече променливи на едно и също място в паметта . Формата за дефиниране и действието на операторите точка (.) и стрелка (->) към член е еднакво като за class .По подразбиране членовете са public . Общата форма е :

union име_на_клас {

// public членове по подразбиране

private :

// private членове

} списък – с –обекти ;



Име_на_клас е името на типа обединение .

Забележка : В С , обединенията могат да съдържат само член променливи и спецификатора private не е позволен . Така С- обединенията могат да съдържат само данни . Например следващия пример създава обединение между double и символен низ и създава променлива наречена my_var :

union my_union {

char time [30] ;

double offset ;

} my_var ;

Обединенията са разгледани по детайлно в Глава 1 .


unsigned



unsigned е модификатор за тип данни който декларира integer без знак . unsigned integer могат да съдържат само положителни стойности .

using

Виж namespace .


virtual

Спецификатора на функция virtual създава виртуална функция . Виртуалната функция е член на базов клас който може да бъде предефиниран от производния клас . Ако функцията не е предефинирана от производния клас се използва дефиницията във базовия клас . Чисто виртуална функция е член функция която няма дефиниция . Това означава че чисто виртуалната функция трябва да бъде предефинирана във производния клас . Чисто виртуалната функция има такъв прототип :

virtual връщан-тип име_на_функция ( списък- с –

параметри ) = 0 ;

Тук връщан тип е връщания тип на функцията , име_на_функция е името и списък – с – параметри определя някакви параметри . Важна характеристика е = 0 . Това казва на компилатора че виртуалната функция няма дефиниция що се отнася до виртуалния клас . Runtime полиморфизма се постига когато виртуалните функции се достигат чрез указател към базов клас . Когато това е направено , типа на обекта определя коя версия на виртуалната функция ще се извика .



Програмен съвет


Клас който съдържа най – малко една чисто виртуална функция се нарича абстрактен . Абстрактния клас не може да бъде използван за създаване на обекти . Той също не може да бъде използван като тип параметър на функция или като връщан тип . Обаче може да създадете указател към абстрактен клас . Клас който наследява абстрактен клас и не прдефинира всички чисто виртуални функции сам по себе си е също абстрактен . Производния клас трябва да предефинира всички чисто виртуални функции от всички свой базови класове преди да стане определен и да могат да се създават обекти от този клас .

void

Спецификатора за тип void е главно използван да декларира изрично че функциите нямат връщана стойност . Той също се използва за създаване на void указатели ( указатели към void ) които са способни да сочат към всеки тип обекти . В С void се използва за деклариране на празен списък с параметри във декларация на функция .


volatile

Модификатора volatile казва на компилатора че променлива може да промени съдържанието си по начини не изрично определени от програмата . Например променливи които могат да бъдат променени чрез хардуера като часовника , прекъсвания или други начини , тръбва да бъдат декларирни като volatile .


wchar_t



wchar_t определя широко- символен тип . Широките символи са дълги 16 бита .

while

Цикъла while има тази обща форма :

while (условие ) {

блок- със – изрази

}

Ако има само един израз във while тогава скобите могат да се пропуснат . while проверява условието на върха на цикъла . По този начин ако условие е false в началото цикъла няма да се изпълни нито веднъж . Условие може да бъде всякакъв израз . Следващото е пример за while цикъл .Той ще прочете 100 символа и ще ги постави във масив от символи :

char s [256] ;

t = 0 ;

while ( t < 100 ) {

s [t] = stream . get ( ) ;

t++ ;

}


Каталог: books
books -> Тайнствената сила на пирамидите Богомил Герасимов Страхът на времето
books -> В обятията на шамбала
books -> Книга се посвещава с благодарност на децата ми. Майка ми и жена ми ме научиха да бъда мъж
books -> Николай Слатински “Надеждата като лабиринт” София, Издателство “виденов & син”, 1993 год
books -> София, Издателство “Българска книжница”, 2004 год. Рецензенти доц д. ик н. Димитър Йончев, проф д-р Нина Дюлгерова Научен редактор проф д-р Петър Иванов
books -> Николай Слатински “Измерения на сигурността” София, Издателство “Парадигма”, 2000 год
books -> Книга 2 щастие и успех предисловие
books -> Превръщане на числа от една бройна система в друга
books -> Тантриското преобразяване


Сподели с приятели:
1   2   3   4   5   6   7   8   9   ...   19




©obuch.info 2024
отнасят до администрацията

    Начална страница