Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УМКД_ОБП_Урдабаева.doc
Скачиваний:
113
Добавлен:
01.03.2016
Размер:
1.29 Mб
Скачать

2. Көпше түрдегі мұрагерлік

С++ тағы туынды класс базалық кластың кез–келген санынан туындауы мүмкін. Туынды кластың құрамында бірден көп базалық кластың болуы көпше түрдегі мұрагерлік деп атайды. Синтаксистік көпше түрдегі мұрагерлік жекеше түрдегі мұрагерліктен бірнеше элементтен тұратын база тізімен ерекшеленеді.

Class A

{

};

Class B

{

};

Class C: public A, public B

{

};

Туынды кластың таныстырушы – объектісін қалыптастырғанда, база тізіміндегі базалық кластардың орналасу қалпы (умолчания) конструкторларының шақыруының кезеңімен анықталады.

Бұл қалпы осы объектілерді жою кезінде деструкторлардың шақыруы кезегіне де септігін тигізеді. Бірақ бұл мәселелер алгоритм секілді базалық объектілерге бөлінген памяттер және де бұл релизация сұрағына қатысты болып табылады. Әдетте программист бұған арнайы көңіл бөлмеуі мүмкін.

Шектеу орналғандықтан туынды кластарды хабарлауда база тізіміне бірдей атаудағы класс бірнеше рет кіре алмайды. Бұл, туынды класты қалыптастырғанда қатысқан қайталанатын элементтер базалық кластарды қабылдаған кезде кездеспеуі керек дегенді білдіреді.

Сонымен бірге, бірдей класс белгіленген туынды кластағы бірнеше базалық кластарды қалыптастырғанда қатыса алады. Сондықтан туынды класты қалыптастырғанда қатысқан тура емес базалық кластарға туынды кластың хабарламасына кіру санына еш шектеу қойылмайды.

class A

{

public:

int x0,xA;

};

class B: public A

{

public:

int xB;

};

class C:public A

{

public:

int x0,xC;

};

class D:public B, public C

{

public:

int x0,xD;

};

Бұл мысалда А мен Д класын хабарлауда екі рет тура емес базалық класс ретінде қолданылады.

Туынды кластың құрылымын таныстарғанда ацикличестік графалар, кластар мен объектілердің сызба нұсқасы қолданылады.

Бұрындағы секілді туынды класта көрсетіп бағытталған, ацикличестік графаның ең төменгі бөлігі, сызба нұсқаның төменгі деңгейімен туынды класс пен объект фрагментінен сәйкес келеді.

Біз бұндай объекті фрагменттін белгіленген кластың туынды таныстырушы – фрагменті деп атаймыз.

Графаның жоғарғы бөлігі, сызба нұсқаның жоғарғы деңгейі базалық класс пен объект фрагментіне сәйкес келеді.

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

Бақылау сұрақтары:

  1. Мұрагерлік дегеніміз не?

  2. Мұрагерліктің қандай түрлері бар?

  3. Базалық класс пен туынды класс арасындағы байланыс?

Әдебиеттер:

  1. Г.С. Иванова и др. ООП: Учебник для вузов, М., Изд-во МГТУ им.Баумана, 2003.- 368 с.

  2. А.В. Замулин. Курс лекций: Объектно-ориентированное программирование (С++)

  3. А.В. Замулин. Курс лекций: ООП (С++, Ява, C#)

  4. Бьерн Страуструп. Язык программирования С++. Третье издание. - М.: Изд. Бином, Невский Диалект, 1999.

  5. Г. Шилдт. Самоучитель C++. - Санкт-Петербург, Изд. BHV, 2004.

6-7 дәріс.

Тақырыбы: Амалдарды қайта анықтау. Операторларды қайта жүктеу.

Дәріс мақсаты: амалдарды қайта анықтау, операторларды қайта жүктеу түсініктерімен танысу және операторларды қайта анықтаудың түрлерін, қайта анықталған операторларды шақыру формаларын бөліп көрсету.

Кілттік сөздер: қайта анықтау; жай функция; компонентті функция; операторлы форма; стандартты форма; унарлы операторлар; бинарлы операторлар; меншіктеу операторлары.

Жоспар:

  1. Операторларды қайта анықтау.

  2. Операторларды қайта анықтаудың түрлері.

  3. Унарлы операторларды қайта анықтау.

  4. Бинарлы операторларды қайта анықтау.

  5. Меншіктеу операторларын қайта анықтау

  6. New және delete операторларын қайта анықтау

  1. Операторларды қайта анықтау.

С++ тілінде стандартты анықталатын типтерге қолданылатын операторлар кірістірілген болып табылады. Яғни программист бұл оператордың орындалуына әсер ете алмайды. Дегенмен, С тілі кез- келген операторды жаңа құрылатын кластар үшін қайта анықтау мүмкіндігін қарастырады. Оператор қайта анықталған кезде оның бастапқы мәндерінің бірде бірі жоғалмайдыб тек қана класс объектілері үшін ұқсас мәнді оператор енгізіледі.

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

  • жай(қарапайым) яғни кластан тыс анықталатын функция оператор. Ол бір орынды(бір аргументтен тұратын) және екі орынды(екі аргументтен тұратын) болады.

  • Компонентті, яғни класта анықталған функция оператор. Онда бір аргумент әрқашан класс объектісі болады.

Функция операторының анықталуының жалпы формасы кестеде келтірілген. Кестеде келтірілген сипаттамада @ белгісі кез-келген мүмкін болатын операция <нәтиже типі> қайтарылатын мән типі (көбіне класс типіне сәйкес келеді, бірақ басқа тип блуы да мүмкін)

Операторларды қайта анықтау кезінде төмендегілерді ескеру кажет.

  • *, sizeof, ?, :, #, ##, ::, class:: операторларын қайта анықтауға болмайды.

  • =, [ ], ( ) – операторлары тек қана класс құрамында қайта анықтала алады.

  • Өайта анықталған = операторы туынды кластардан мұрагерленбейді.

  • Операторлардың преаритетін және ассоциотивтігін өзгертуге болмайды.

Функция операторларды сипаттау формалары.

Жай функция

Компонентті функция

бірорынды

<нәтиже типі> operator@(аргумент)

Екіорынды

<нәтиже типі>operator@ ()

екіорынды

<нәтиже типі>operator@(арг1,арг2)

екіорынды

<нәтиже типі>operator@(аргумент2)

Функция оператордың шақырудың екі формасы бар кстандартты және операторлы.Олар келесі кестеде келтірілген.

Функция-операторларды шақыру формалары.

Стандартты форма

Оператор форма

Жай функция үшін

operator@(<аргумент>)

operator@(<арг1><арг2>)

Жай функция үшін

@<аргумент>

<аргумент1>@< аргумент2>

Компонент функция үшін

<аргумент>.operator@()

<арг1>.operator@(<арг2>)

Компонент функция үшін

@<аргумент>

<аргумент1>@<аргумент2>

Кластан тыс функция операторды сипаттаған кезде оған тек кластың ортақ компоненттері ғана қолжетіледі. Егер функция операторға кластың кез-келген компоненттеріне қатынау мүмкіншілігіне ие болу қажет болса, онда оны friend спецификаторымен осы класқа достық функия ретінде анықтау қажет.

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

Мысалы:компонентті функция операторды сипаттау.

#include <string.h>

#include<stdio.h>

#include<iostream.h>

#include<conio.h>

class sstr // жол класы

{ private: //класстың жасрын жолдары.

Char *str;

Int len;

Public: //класстың баршаға қолжетілу жолдары.

Void print (void)

{ cout <<” жасырын жолдардың ішіндегісі:” << endl;

cout<<”жол”<<str<<endl;

cout<<”жол ұзындығы:”<<len<<endl; }

str(){ }

sstr(char *vs)

{ len =strlen(vs); str-new char[len+1]; strcpy(str,vs); }

~sstr() {delete str;}

Sstr & operator +(sstr&); /*екіорынды операцияны жүзеге асыратын компонентті функцияның прототипі”+” */

Sstr & operator-(); /*бірорынды операцияны жүзеге асыратын компонентті функцияның прототипі”-” */

sstr & sstr::operator-()

{ char c;

for (int i=0; i<=len/2-1; i++) {c=str[i]; str[i]=str[len-1]; str[len-i-1]=c;}

return *this; }

sstr & sstr ::operator ++(sstr &A)

{ int l-A.len+len; char *s; s=bew char[l+1]; strcpy(s,str);

strcat(s,A.str); len=l; str=s; return *this; }

void main()

{ clrscr();

Sstr aa(“қолдану мысалы”);

sstr bb(“операцияларды қайта анықтау”);

sstr cc=aa+bb; //шақырудың операторлық формасы

cc.print();

sstr dd; dd=aa.operator+(bb); //шақырудың қалыпты формасы

dd.print();

-aa; -bb; // унарлы минустың қолданылуы-жолдарды қарату

aa.print(); getch(); }

Кейбір операцияларды олардың комутативтілігін қамтамасыз ету үшін қайта анықтау класс денесіндегі функция-операторлар-дың бірнеше варианттарын сипаттау керек.

С++ енгізу-шығару кітапханасының кластарымен жұмыс жасауда енгізу-шығару кластары “<<” (ағымға қосылу) және “>>” (ағымнан шығару) операцияларын мәліметтердің тек қана қалыпты типтеріне ғана қолданады. Сондықтан жолдар типін белгілі-бір қолданушы кластар үшін де, және тұтас кластар үшін де бұл класс объектілерін шығарған кезде “<<” және ”>>” операцияларын әрбір класс үшін қайта анықтаған жөн.

“Ағымға қосылу” және “ағымнан шығару” операцияларын қайта анықтауда операцияларды сипаттаудың келесі формасы қолданылады:

Operator & operator<<(ostream & out,<жаңа тип><аты>)

{<функция-оператор денесі>};

Istream & operator >>(istream & in,<жаңа тип>&<аты>)

{<функция-оператор денесі>}.

Бұл операцияларға private және proected сипатталған жолдарды кірістіру кезінде “<<” және “>>” операцияларын серіктестік ретінде сипаттаған дұрыс.

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