Программалық қамтамаларды құру арнайы жабдықтары



бет2/3
Дата16.06.2016
өлшемі399 Kb.
#138777
түріПрограмма
1   2   3
§9 Тұрақты әдістер
Тұрақты әдістер кластың өрістерінің мәндерін өзгертпейді.

//constfu.cpp

class aClass

{ private: int alpha;

public: void nonFunc( )

{alpha=99;}

void conFunc ( ) const //қате

{alpha=99;}

};

Функцияны тұрақты ету үшін оның прототипінен кейін, бірақ денесінің алдында const қызметші сөзін жазу керек. Егер функцияның жариялануы және анықталынуы бөлек берілсе, онда const модификаторы екі рет жазылады. Тек кластың өрістерінің мәндерін оқитын әдістерді тұрақты әдістер ретінде қолдану тиімді.



Мысалы, Distance класының showdist() әдісін тұрақты ету керек. Сол сияқты engeset.cpp программасындағы add_dist() әдісі де берілгендердің мәндерін өзгертпеу керек. Егер функция аргументін сілтеме арқылы беріп, сонымен қатар оның мәнін өзгертпеу крек болса, онда аргументті тұрақты ету керек. Ол үшін add_dist() әдісінің d2 параметрі const модификаторымен сипатталған.

//engeconst.cpp

#include

class Distance

{private:

int feet


fleat inches;

public:


Distance ():feet (0), inches (0.0)

{}

Distance (intft,float in): feet (ft),



Inches (in)

{}

void getdist( )



{cout<<”\n введите фут=”; cin>>feet;

cout<<”\n введите дюйм=”; cin>> inches;

}

void showdist( ) const



{cout<

Distance add_dist (const Distance &) const;

};

Distance Distance : : add_dist (const Distance &) const;



{ Distance temp;

// feet=0; ошибка

// d2.feet=0 ошибка

temp.inches = inches + d2.inches;

if (temp.inches >= 12.0)

{temp.inches - = 12.0;

temp.feet = 1;

}

temp.feet + = feet + d2.feet;



return temp;

}

int main ( )



Distance dist1, dist3;

Distance d2 (11, 6.25);

dist1.getdist ( );

dist3 = dist1.add_dist (dist2);

cout<< ” \ dist1=”; dist1. showdist ( );

cout<< ” \ dist2=”; dist2. showdist ( );

cout<< ” \ dist3=”; dist3. showdist ( );

cout << endl;

return 0;

}
§10 Тұрақты объектілер


const модификаторын объектілерге де қолдануға болады. Егер объект const модификаторымен сипатталса, онда оны өзгертуге болмайды. Мұндай объектілер үшін тек тұрақты әдістерді ғана шақыруға болады. Мысалы:

// constObj.cpp

# include

class Distance

{ private:

int feet


fleat inches;

public:


Distance (intft,float in): feet (ft), inches (in)

{}

void getdist ( )



{cout<<”\ n введите фут =”; cin>>feet;

cout<<”\ n введите дюйм =”; cin>> inches;

}

void showdist ( ) const



{cout << feet<< ” \ ’-“ << nches < ’ \ ” ’;}

}

int main( )



{const Distance football (300,0);

// football.getdist( ); - қате

cout<< ” Длина поля = ”; football.showdist( );

cout<

return 0;

}

Американдық футбол алаңының ұзындығы 300 футқа тең. football объектісі - тұрақты объект. Сондықтан тек тұрақты әдістерді ғана шақыра аламыз.


§11 Операцияларды асыра жүктеу
Операцияларды асыра жүктеу - объектілі бағытталған программалаудың ең күрделі мүмкіндіктерінің бірі.

Жаңа кластарды құру және операцияларды асыра жүктеу С++ тілінің мүмкіншілігін кеңейтуге жол ашады. Жаңа кластар үшін операцияларды асыра жүктеу арқылы программистер жаңа өз тілін құра алады.


Унарлы операцияларды асыра жүктеу
Унарлы операцияның тек бір ғана операндасы болады (операнд дегеніміз операция әрекет жасайтын айнымалы). Унарлы операцияның мысалы ретінде инкрементті, декрементті алуға болады.

Алдыңғы тақырыптарда қарастырылған Counter класының с1 объектісі қосқышының мәнін 1-ге арттыру үшін с1.inc_count() әдісі шақырылған болатын.

Программа мәтіні түсінікті болу үшін ++с1 жазуы ыңғайлы болар еді. Осы операцияны асыра жүктеу программасын қарастырайық.

// countpp1.cpp

# include

class Counter

{ private:

unsignet int count;

public:

Counter ( ) : count (0)



{}

unsigned int get_count(0)

{return count;}

void operator ++( )

{++count;}

};

int main ( )



{ Counter c1, c2;

cout << ”\ n c1 = “ <

cout << ”\ n c2 = “ <

++c1;


++c2;

++c2;


cout << ” \ n c1 = “ <cout << ” \ n c2 = “ <

count << endl;

return 0;

}

Жауабы: с1=0



с2=0

с1=1


с2=2

++ операциясын асыра жүктеу үшін operator қызметші сөзі қолданылған.

Алдымен қайтарылатын тип көрсетіледі (біздің жағдайда void типі), содан соң operator қызметші сөзі, кейін операция белгісі ++ және жақша ішінде көрсетілген аргументтер тізімі жазылады. Біздің жағдайда жақша іші бос. Бұл синтаксис компиляторға программа мәтінінде ++ операциясының операнды Counter класына тиісті болса осы функцияны шақыру керектігін көрсетеді.

Компилятор асыра жүктелген функцияларды берілгендер типтеріне және аргумент сандарына қарай ажыратады. Сол сияқты асыра жүктелген операцияларды операндалардың типтеріне қарай ажыратады.

Біздің жағдайда operator ++( ) функциясының аргументтері жоқ. Олай болса бұл операция нені өсіреді? Ол операцияны шақырып тұрған объектінің count өрісінің мәнін өсіреді. Класс әдістерінің өзін шақырып тұрған осы кластың объектісін көре алатындықтан операция үшін аргументтің қажеті жоқ.

countpp1.cpp программасындағы operator++() функциясының кішкене кемшілігі бар. Егер біз с1 = ++ с2; меншіктеу операторын жазсақ компилятор қате береді. Себебі operator ++() функциясы void типін қайтарады. Ал меншіктеу операторы Counter типін қайтаруын сұрайды. Яғни меншіктеу өрнектерінде operator ++() функциясын қолдану үшін қайтарылатын типті дұрыс анықтауымыз керек. Мысалы:

// countpp2.cpp

# include < iostream.h >

class Counter

{ private:

unsignet int count;

public:


Counter ( ) : count (0)

{}

unsigned int get_count(0)



{return 0;}

Counter operator ++( )

{++count;

Counter temp;

temp. count = count;

return temp;

}

};

int main ( )



{ Counter c1, c2;

cout << ” \ n c1 = “ << c1. get_count ( );

cout << ” \ n c2 = “ << c2. get_count ( );

++c1;


c2 = ++c1;

cout << ” \ n c1 = “ << c1. get_count ( );

cout << ” \ n c2 = “ << c2. get_count ( );

count << endl;

return 0;

}

Программаның бұл мәтінінде operator ++() функциясында Counter класына тиісті жаңа объект анықталған. Объект алдымен өзінің count өрісінің мәні арттырады, содан соң temp объектісінің count өрісіне меншіктелініп, негізгі программаға қайтарылады. temp объектісін қолдану үшін программа мәтінінде 3 жол қажет болды. Осы әрекеттерді орындау үшін есімсіз объектіні қолданатын тағы бір әдіс бар.



// countpp3.cpp

# include

class Counter

{ private:

unsignet int count;

public:


Counter ( ) : count (0)

{}

Counter (int c) : count (c)



unsigned int get_count (0)

{return count;}

Counter operator ++( )

{++count;

return Counter (count);

}

};



int main ( )

{ Counter c1, c2;

cout << ” \ n c1 = “ << c1. get_count ( );

cout << ” \ n c2 = “ << c2. get_count ( );

++c1;

c2 = ++c1;



cout << ” \ n c1 = “ << c1. get_count ( );

cout << ” \ n c2 = “ << c2. get_count ( );

count << endl;

return 0;

}

Программа мәтініндегі



return Counter (count);

жолы типі Counter есімсіз объект құрып негізгі программаға қайтарады. Бұл объект басқа еш жерде қолданылмайтындықтан объект есімсіз болып тұр. Объектінің мәні count параметрінің мәнімен анықталған. Көрсетілген жол дұрыс жұмыс істеу үшін бір аргументі бар конструктор алдын-ала анықталынуы керек.


Постфиксті операция
Мәні қолданылып болғаннан кейін мәнін арттыратын постфиксті операция үшін асыра жүктеуді қалай орындау керек екендігін қарастырайық. ++ операциясын асыра жүктеудің екі әдісін келтірейік.

// postfix.cpp

# include < iostream.h >

class Counter

{ private:

unsignet int count;

public:

Counter ( ) : count (0)



{}

Counter (int c) : count (c)

unsigned int get_count (0)

{return count;}

Counter operator ++ ( )

{return Counter (++ count);}

}

Counter operator ++( int )



{return Counter (++count ++);

}

};



int main( )

{ Counter c1, c2;

cout << ” \ n c1 = “ << c1. get_count ( );

cout << ” \ n c2 = “ << c2. get_count ( );

++c1;

c2 = ++c1;



cout << ” \ n c1 = “ << c1. get_count ( );

cout << ” \ n c2 = “ << c2. get_count ( );

c2 = c1++

cout << ” \ n c1 = “ << c1. get_count ( );

cout << ” \ n c2 = “ << c2. get_count ( );

return 0;

}

Мысалда operator ++() функциясының екі түрі бар.



Counter operator ++ ( ) және

Counter operator ++ ( int )

Бұл жерде int аргумент ролін атқармайды. Компилятор үшін ++ операциясының постфиксті версиясын қолдану жөнінде белгі болып табылады. Программаның орындалу нәтижесінде келесі нәтижелерді аламыз:

с1=0


с2=0

с1=2


с2=2

с1=3


с2=2

Арифметикалық операциялар
Осы уақытқа дейін Distanse класының объектілерін қосу үшін add_dist() әдісі қолданылып келді:

dist3.add_dist(dist1, dist2);

+ операциясын асыра жүктеу арқылы келесі түрде жазуға болады:

dist 3 = dist1 + dist2;

// engplus. cpp

# include

class Distance

{ private:

int feet;

float inches;

public:

Distance ( ) : feet (0) , inches (0)



{ }

Distance ( int ft , float in ) : feet (ft) , inches ( in)

{ }

void getdist ( )



{ cout << ” \ n Футты енгізіңіз = “ ; cin >> feet;

cout << “ \ n Дюймді енгізіңіз = “; cin >> inches ;

}

void showdist ( )



{

cout << feet << ” \ ‘ – “ << inches << ‘ \ “ ‘;}

Distanse operator + ( Distanse ) const;

};

Distanse Distanse: : operator + ( Distanse d2) const;



{ int f = feet + d2. feet;

float i = inches + d2. inches;

if (i >= 12.0)

{ i - = 12.0

f ++;

}

return Distance(f, i);



int main ( )

{ Distance dist1, dist3, dist4;

dist1. getdist ( );

Distance dist2 (11, 6.25);

dist3 =dist1+ dist2;

dist 4 = dist1 + dist2+ dist3;

cout << ”dist1 = “; dist1. showdist ( ); cout << endl;

cout << ”dist2 = “; dist2. showdist ( ); cout << endl;

cout << ”dist3 = “; dist3. showdist ( ); cout <

cout << ”dist4 = “; dist4. showdist ( ) ;cout << endl ;

return 0;

}

С++ тілінде страуктураның немесе класстың мүшесін алу операциясын (.), келісім беру операциясын (:: операция разрешения), шартты операцияны (?:), көрсеткіш бойынша берілгенді алу операциясын (->) асыра жүктеуге болмайды.


§12 Мұрагерлік
Мұрагерлік дегеніміз алдын-ала бар кластардан туынды кластарды құру. Алдын-ала бар класты негізгі (базалық) класс деп, ал мұрагер класты туынды класс деп атаймыз. Туынды класс негізгі кластың барлық мүмкіндіктерін қабылдаумен қатар, өзінің мүмкіндіктерінде дамыта алады. Бұл жағдайда негізгі класс өзгеріссіз қалады. Мұрагерлік бар кодты бірнеше рет қайталап қолдануа мүмкіндік береді. Туынды класты алу үшін класс есімімен кейін қос нүкте, содан соң public сөзінен кейін негізгі кластың есімі көрсетіледі. Біз кластың private және public бөліктерінің бар екендігін білеміз. Кластың ішінде рrivate бөліктердегі берілгендер мен әістерді көре аламыз. Ал сырттан тек public бөлігіндегі берілгендер мен функцияларды көруге болады.

Туынды кластар негізгі кластың private бөлігіндегі берілгендер мен функцияларды қолдана алмайды. Енді класқа қосымша тағы бір бөлік қосылады. Ол protected бөлігі. Бұл бөліктегі берілгендер мен функциялар туынды кластарға public бөліктегі берілгендер мен функциялар қоса көрінеді. Тек кластың ішінде ғана private бөліктегі берілгендер мен функцияларды көруге болады. Мысалы ,программада анықталған класс объектісі тек public бөліктегі берілгендер мен функцияларды қолдана алады.

Төменде мұрагерлікке байланысты көре алу кестесі берілген.
Мұрагерлік және көре алу кестесі



Көре (ала) алу спецификаторлары


Кластың ішінде көру


Туынды кластарда көру

Сыртқы кластарда, функцияларда көру

public

Бар

бар

бар

protected

Бар

бар

жоқ

private

Бар

жоқ

жоқ

# include

class Counter

{ protected:

unsigned int count;

pablic:


Counter ( ): count (0)

{}

Counter (int c ): count (0)



{}

unsigned int count ( )

{return count;}

Counter operator ++( )

{return Count (++count);}

};

class Count Dn: public Counter



{ public:

Counter operator - - ( )

{return Count (count - - );}

};

void main ( )



{ Count Dn c1;

cout << “ \ n c1=” << c1.get_count ( );

++c1;

cout << “ \ n c1=” << c1.get_count ( );



- - c1;

cout << “ \ n c1=” << c1.get_count ( );

}

CountDn класы Counter класының конструкторын қолдана алады, ал Count Dn класының объектілері үшін бұл жағдайда негізгі Counter класының бір аргументті конструкторын қолдануға болмайды. CountDn класы үшін конструкторды анықтаймыз:



class Count Dn: public Counter

{ public:

Count Dn ( ): Counter ( )

{}

Count Dn (int c): Counter (с )



{}

Count Dn operator - - ( )

{return Count (- - count );}

};
class А - класс әдістері өзінің ішіндегі private бөліктегі де, public бөліктегі берілгендерді көре алады;



тиым салынған, яғни А класының объектісі

private бөліктегі берілгендерді көре алмайды.


А класының объектісі тек public бөліктегі

берілгендерді ғана көре алады.

obj A


Енді мұрагерлік жағдайдағы көру спецификаторларын қарастырайық:


class В базалық класы

Туынды класс D

class D: public


obj B
obj D



Кластар иерархиясы

Бір компанияның қызметкерлері жөнінде мәліметтер базасын құру керек болсын. Компаниядда қызметкерлердің үш категориясы жұмыс істесін, яғни менеджерлер, ғалымдар және жұмысшылар. Базада қызметкерлердің есімі және идентификциялық номерлері, сонымен қатар менеджерлер үшін олардың қызметінің есімі, гольф-клубқа төлейтін взностың нөмері, ғалымдар үшін олардың жарық көрген ғылыми еңбектер саны қажет болсын.

Бұл программаны құру үшін empogee базалық класын сипаттаудан бастаймыз. Класта қызметкердің фамилиясы және номері беріледі және оларды енгізу және шығару әдістері беріледі. Бұл кластан туынды manager, scientist және laborer кластары алынады. Олар қосымша ақпараттарды қабылдайды.

emplogee


- private

- public
manager scientist laborer

manager scientist laborer

foreman

foreman
Енді жұмысшылардың ішінде бригадир бар болатын болсын, онда туынды laborer класынан туынды foreman туынды класын аламыз. Бригадир жұмыс жоспарының орындалуын қадағаласын. Яғни туынды кластардан да туынды класты алуға болады.



#include

cons tint LEN=80;

class employee

{private:

char name[LEN];

unsigned long number;

public:

void getdata()



{cout<<”\n Фамилияны енгізіңіз:”; cin>>name;

cout<<” Номерді енгізіңіз:”; cin>>number;

}

void putdata() const



{cout<<”\n Фамилия:”<

cout<<”Номер:”<

}

};

class manager: public employee



{private:

char title[LEN];

double dues;

public:


void getdata()

{

empoyee::getdata();



cout<<”Жұмыс орнын енгізіңіз:”; cin>>title;

cout<<”Салымды енгізіңіз:”; cin>>dues;

}

void putdata()



{

employee::putdata();

cout<<”\n Қызметі:”<

cout<<”\n Салым көлемі: ”<

}

};

class scientist: public employee



{private:

int pubs;

public:

void getdata()



{

employee::getdata();

cout<<”Жарыққа шыққан шығармалар санын енгізіңіз:”;cin>>pubs;

}

void putdata()



{

employee::putdata();

cout<<”\n Шығармалар саны: ”<

}

};



class laborer: public employee

{

};



class foreman: public laborer

{private:

float quotas;

public:


void getdata()

{

laborer::getdata();



cout<<”Өндірілген өнімнің көлемін енгізіңіз:”; cin>>quotas;

}

void putdata()



{

laborer::putdata();

cout<<”\n Көлем:”<

}};


int main()

{laborer l1;

foreman f1;

cout<<”\n Бірінші жұмысшы жөнінде ақпаратты енгізіңіз:”;

l1.getdata();

cout<<”\n Бірінші бригадир жөнінде ақпаратты енгізіңіз:”;

f1.getdata();

cout<<<<”\n Бірінші жұмысшы жөнінде ақпарат:”;

l1.putdata();

cout<<”\n Бірінші бригадир жөнінде ақпаратты енгізіңіз:”;

f1.putdata();

cout<

return 0;

}

Кластың әдістерін алуды реттеп отыруға болады. Оның бірі туынды кластарды анықтау барысында. Осы уақытқа дейін туынды класты public сөзінің көмегімен алдық. Яғни туынды кластың объектілері базаық кластың public бөлігіндегі берілгендерді көре алады. Енді private сөзінің көмегімен де туынды кластарды анықтауға болады. Бұл жағдайда туынды кластың объектілері, базалық кластың public бөлігіндегі берілгендерді ала алмайды.



class A

class C: private A

class B:public A

obj A


obj B obj C

§13 Виртуальді әдістер
Виртуальді деген сөз көрінеді, бірақ нақты өмірде жоқ дегенді білдіреді. Виртуальді функцияларды қолдану барысында программа белгілі бір кластың функциясын шақырп тұрған сияқты, бірақ басқа кластың функциясы орындалады. Келесі мысалды қарастырайық.

#include

class Base

{public:


void show()

{cout<<”Base\n”;}

};

class Dev1: public Base



{public:

void show()

{cout<<”Dev1\n”;}

};

class Dev2 : public Base



{public:

void show()

{cout<<”Dev2\n”;}

};

void main()



{ Dev1 dv1;

Dev2 dv2;

Base* ptr;

ptr=&dv1;

ptr->show();

ptr=&dv2;

ptr->show();

}

Программада Dev1, Dev2 кластары - Base базалық класының туынды кластары. Әр класта show() функциясы анықталған. main() функциясында Dev1, Dev2 кластарының объектілері және Base класына көрсеткіш анықталған. Туынды кластың адресі базалық кластың көрсеткішіне меншіктелген. ptr->show() функциясы туынды класттың функциясын шақыру керек болып көрінгенмен, базалық класқа тиісті функция шақырылады. Программаны экранға келесі ақпарат шығарады:



Base

Base


Туынды кластардың функцияларын орындату үшін негізгі кластағы show() функциясының жариялануының алдына virtual қызметші сөзін жазамыз.

#include

class Base

{public:


virtual void show()

{cout<<”Base\n”;}

};

class Dev1: public Base



{public:

void show()

{cout<<”Dev1\n”;}

};

class Dev2 : public Base



{public:

void show()

{cout<<”Dev2\n”;}

};

void main()



{ Dev1 dv1;

Dev2 dv2;

Base* ptr;

ptr=&dv1;

ptr->show();

ptr=&dv2;

ptr->show();

}

Программаның орындалу нәтижесінде экранда



Dev1

Dev2


ақпаратын аламыз, яғни туынды кластың функцияларының жұмыс істегені көрініп тұр. Функциялардың бұлай шақырылуы кешіктіріліп байланыс құру деп аталады.

Объектілері ешқашан қолданылмайтын, бірақ туынды кластарды құру үшін қажет негізгі кластарды, яғни кластар иерархиясын құру үшін, абстракты кластар дейді. Абстракты класты ретсіз қолданудан программада қорғау үшін класқа таза виртуальді функция енгізеді. Таза виртуальді функция дегеніміз оның жариялануынан кейін ‘=0’ өрнегі көрсетілген функция. Жоғарыдағы мысалда Base класын келесі түрде анықтасақ

class Base

{public:


virtual void show()=0;

};

онда Base класының объектісін құру кезінде компилятор қате жөнінде хабарлама береді. Көп жағдайларда, мысалы операцияларды асыра жүктеу барысында, объектінің өзіне өзі сілтейтін көрсеткіш қолданылады. Ол this қызметші сөзімен анықталады.


§14 Көпфайлды программалар
Файларалық айнымалылар
Алдымен жариялаумен анықтаудың арасындағы айырмашылықты қарастырайық. Жариялау барысында жай анымалының типін және есімін көрсетеміз. Жариялау барысында бірден жадыдан орын бөлінбейді. Айнымалыны анықтау барысында ғана жадыдан орын бөлінеді. Яғни анықтау барысында ғана нақты айнымалы құрылады.

Бірақ көпшілік жариялаулар бір мезгілде анықтаулар да болып келеді. Тек жалғыз ғана extern сөзі қолданылған жариялау анықтау болып есептелмейді, яғни бұл сөзбен сипатталған жариялау үшін жадыдан орын бөлінбейді.

int sv; - жариялау және анықтау

extern int v; - тек қана жариялау.

Глобальді айнымалы программа бірнеше файлдардан тұрса да, бір ғана рет анықталынуы қажет. Программа А және В файлдарынан тұрсын.

Файл А


int globv; - А файлында анықтау

Файл В


int globv; - қате жариялау.

Егер келесі түрде жазсақ, олда қате болады:

Файл А

int globv; - А файлында анықтау



Файл В

globv=3; - қате, себебі В файлында А файлындағы анықтау көрінбейді.

Бұл қателерді extern сөзін қолдану арқылы жоя аламыз.

Файл А


int globv; - А файлында анықтау

Файл В


extern int globv; - extern сөзі бұл тек жариялау екендігін көрсетеді. Жадыдан

globv=3; орын бөлінбейді. А файлындағы globv айнымалысы В

файлында да көрінеді.

еxtern жариялауында бірден инициализациялауға болмайды.

Егер әртүрлі файлдарда бірдей есімді глобальді айнымалылырды қолдану керек болса, онда оларды static қызметші сөзінің көмегімен сипаттау керек. Ол кезде глобальді айнымалының көріну облысы файлдың көлемі болады, яғни сондай есіммен басқа айнымалыларды (жадыда бөлінген орындар) өзге файлдарда қолдана беруге болады.

Файл А


static int globv; - тек А файлында көрінеді

Файл В


static int globv; - тек В файлында көрінеді

const сөзінің көмегімен сипатталған айнымалы тек сол файлда ғана көрінетіндігін білеміз. Бірақ оны басқа файлдарда да көрінетін етуге болады. Ол үшін extern сөзін қолдану керек.

Файл А

еxtern const int с=99; (анықтау)



Файл В

еxtern const int с; - жариялау. В файлында А файлында анықталған с көрінеді.


Файларалық функциялар
Функцияны жариялау дегеніміз оның есімін, қайтаратын типін және аргументтерінің типтерін көрсету. Анықтау дегеніміз – ол жариялау және функияның коды. Сондықтан функцияларды бір файлда анықтап, басқа файлдарда жариялап, содан соң шақыра беруге болады.

Файл А


int add(int a, int b) – функцияны анықтау

{return a+b;}

Файл В

int add(int, int); - функцияны жариялау



....................

int d=add(2,3); - функцияны шақыру

Бұл жағдайда extern сөзінің қажеті жоқ. Айнымалылар сияқты функцияны да басқа файлда көрсетпеуге болады.

Файл А


static int add(int a, int b) - функцияны анықтау

{return a+b;}

Файл В

static int add(int a, int b) - басқа функция



{return a+b;}

Файларалық кластар
Кластың жай айнымалыдан өзгешелігі, класты анықтау жадыдан орын бөлуді білдірмейді. Ол тек класқа нелер кіретіндігін, яғни құрамын көрсетеді. Сондықтан кез келген файлдан класты көру үшін әр файлда класты қайта анықтау керек.

Көптеген компиляторлар көпфайлды қосымшаларды басқарады, оларды проекттер деп атайды. Файлдарды біріктіру жөнінде ақпарат арнайы файлда сақталады. Ол проект файлы деп аталады. Microsoft ортасында проекттінің кеңеймесі .DSP болады. Проект файлы автоматты түрде жаңарып отырады. Негізгі және тақырыптық файлдар компиляцияланып, .OBJ және .LIB файлдары біріктіріліп орындалатын .EXE файлы құрылады.

Тақырыптық файлда класты қайталанып анықталуынан қорғау үшін файлды келесі препроцессор директивасынан бастау керек:

#if !defined (My_cl) - егер My_cl лексемасы анықталмаса

#define My_cl - оны анықтау

............ - класты анықтау

#endif - директиваның шартын жабу

Бұл әдісті тақырыптық файлды негізгі файлдарға бірнеше рет қосу керек болған жағдайларда қолдану қажет.

Көпфайлды проектіні құру алгоритмі:

1. Projects -> Win 32 Console Application

2. Проект есімін енгізу

3. File -> New -> Files

4. C/C++ Header File

5. Тақырыптық файл есімін енгізу

6. Тақырыптық файл мәтінін енгізу

7. File -> New ->Files

8. C++ Source ->File

9. Кеңеймесі .срр болатын класс әдістерімен негізгі программа сақталатын файл есімін енгіземіз

10. Build – компиляциялау және біріктіру

11. Execute – орындау.

Екі бағытталған тізім негізінде құрылған көпфайлды программа мысалы:

// m_cl_cl.cpp файлы

#include "m_cl.h"

void main()

{

pl d,d2,d3;



int xx;

for (int i=0;i<=3;i++)

{

cout<<"vv x=";



cin>>xx;

d.inafter(xx);

}

p* ptr;


ptr=d.get_cl_fore();

d.out(ptr);

ptr=d.uk(2);

d.del(ptr);

ptr=d.get_cl_fore();

d.out(ptr);

cout<<"2 kolc"<<'\n';

for (i=0;i<=3;i++)

{

cout<<"vv x=";



cin>>xx;

d2.inafter(xx);


}

d3=d+d2;


ptr=d3.get_cl_fore();

d3.out(ptr);

d.r();

d2.r();


d3.r();

}

//m_cl.cpp файлы



#include "m_cl.h"

p* pl::uk(int k)

{

p* ptr;


ptr=cl;

for (int i=1;i<=k;i++)

{ptr=ptr->fore;}

return ptr;}

void pl::inafter(int xx)

{p* young=new p;

young->x=xx;

young->fore=cl->fore;

young->aft=cl;

cl->fore->aft=young;

cl->fore=young;

}

void pl::out(p* ptr)



{

if (ptr!=cl)

{cout<<"kolc="<
x<<'\n';

out(ptr->fore);

}

}

void pl::del(p* old)



{old->fore->aft=old->aft;

old->aft->fore=old->fore;

}

pl pl::operator+(pl pl1) const



{ p* ptr,ptr1;

ptr=this->cl->aft;

this->cl->aft->fore=pl1.cl;

this->cl->aft=pl1.cl->aft;


pl1.cl->aft->fore=this->cl;

pl1.cl->aft=ptr;

return *this;

}

// m_cl.h файлы



#include

#if !defined (My_cl)

#define My_cl

struct p


{

int x;


p* fore;

p* aft;


};

class pl


{private:

p* cl;


public:

pl()


{

cl=new p;

cl->x=100;

cl->aft=cl;

cl->fore=cl;

cout<x<<'\n';

cout<aft<<'\n';

cout<fore<<'\n';

}

p* get_cl_fore()



{return cl->fore;}

void inafter(int);

void out(p*);

void del(p*);

p* uk(int);

pl operator+(pl) const;

void r()

{cout<<"adr="<

};

};

#endif




Достарыңызбен бөлісу:
1   2   3




©dereksiz.org 2024
әкімшілігінің қараңыз

    Басты бет