Автор: Пользователь скрыл имя, 11 Февраля 2013 в 21:00, лабораторная работа
Полиморфизм(polymorphism грек тілінен)- бұл техникалық әртүрлi есептерді, бірақ ұқсас екі немесе бірнеше есепті шығару үшін бірдей атты қолдануға мүмкiндiк беретін қасиет. Полиморфизмның объектіге бағытталған программалауда қолдану мақсаты, бір атты тапсырмасы ортақ класс әдістері (для класса действий) үшін қолдану болып табылады. Әрбiр нақты әдістердің (действия) орындалуы мәлiметтер типімен анықталады.
Қандай да бір виртуалды функцияны шақырған кезде, (бағдарламаны орындау кезіндегі) нұсқағыштың типіне емес, сол іс жүзінде бағытталған нұсқағыштың объект типіне тәуелді болады.
Статикалық емес функция мүшелері ғана виртуалды бола алады.
Виртуалдылық мұра етіледі. Функция виртуалды болып анықталғаннан кейін, оның қайталанған анықтамасы туынды класста (сол сияқты түп тұлғамен) жаңа виртуалды функция құрады және де virtual спецификаторы қолдана алмайды.
Конструкторлардың деструкторлардан айырмашылығы виртуалды бола алмайды. Әрбір класс виртуалды функция болу үшін, виртуалды деструктор болуы тиіс.
1.5 Абстракты класстар
Абстрактілі деп ең болмағанда бір таза (бос) виртуалды функциясы бар классты айтады.
Таза виртуалды функция компонентті функция деп аталады, және келесі анықтамадай болып анықталады :
virtual
тип аты_функция(формальды_
Таза виртуалды функция ештеңе істемейді және шақырулар үшін қол жетімсіз. Оның тағайындалу негізі - туынды класстарда функцияларды алмастыру үшін қызмет көрсетеді. Абстрактілі класс базалық сапада тек қана негізгі туындылар үшін қолдана алады.
Абстрактілі класс механизмі болашақта нақты жоспар құруға игерілген. Осы кезде иерархиялық класстың құрастырылуы келесі схема бойынша орындалады. Бастапқыда иерархиялар абстрактілі базалық класс болады. Ол мұрагерлік интерфейс болу үшін қолданып жатыр. Туынды класстар бұл интерфейсті дәлелдейді және жүзеге асырады. Абстрактілі класста абстрактілі әдістері бар таза виртуалды функциялар жарияланған.
Мысал:
#include<iostream.h>
class Base
{
public:
Base();
Base(const Base&); // көшіру конструкторы
virtual ~ Base(); // виртуальды деструктор
virtual void Show()=0; // таза виртуальды функция
//басқа таза виртуальды функциялар
protected:
private:
// жиi бос қалады,
немесе әзірлеулерге (
};
class Derived:virtual public Base
{
public:
Derived();
Derived(const Derived&); //көшіру конструкторы
Derived(); //параметрі бар конструктор
virtual~Derived();
void Show(); //алдын ала анықталған виртуалды функция
//басқа алдын
ала анықталған виртуалды
//басқа жүктелген операциялар
protected:
//мұралану
болатын жағдайда private орнына
қолданылады
private:
//реализациалар бөлшектері үшін қолданылады
};
Абстрактілі класс объектісі функцияның формальды параметрі бола алмайды, бірақ абстрактілі класқа нұсқағыш формальды параметр бола алады. Бұл жағдайда шақырылған функцияны өндірістік объектіге нұсқағыштың мәнін фактілік параметр ретінде нұсқағышты абстрактілі базалық класқа ауыстра отырып жіберуге мүмкіндік пайда болады. Осындай жолмен біз полиморфты объектілерді аламыз.
Абстрактілі әдіс алдын ала анықталуды жалпылау түрінде қаралуы мүмкін. Екі жағдайда да ұрпағы үшін ата-аналық кластың тәртібі өзгереді. Алайда, абстрактілік әдіс үшін тәртібі анықталмаған. Кез келген тәртіп өнтірістік класс түрінде беріледі.
Абстрактілі кластың артықшылықтарының бірі таза тұжырымдалған болып табылуы: программалаушы жоғарғы дәрежелі абстракциыны қаншалықты тиімді болғанша керек әрекеттерге ойша бөле алады. Мысалы, геометриялық пішіндер үшін біз TTriangle үшбұрышын, TCircle шеңберін, TSquare шаршысын салатын Draw әдісін анықтай аламыз. Біз абстрактілі ата-аналық класс TGraphObject үшін де аналогтық әдісті анықтаймыз. Алайда бұл тәсіл класта болғандықтан пайдалы жұмысты атқара алмайды.
TGraphObject-та бір нарсені сызуға ақпарат жеткіліксіз. Сонда да Draw әдісінің бар болуы TTriangle ,TCircle, Tsquare ішкі кластарына арналған үш тәуелсіз концепцияларды шығармай, TGraphObject класымен функционалдылықты тек бір рет байланыстыруға мүмкіндік береді.
Абстрактілі әдісті қолданудың актуальдырақ тағы да бір себебі бар.С++ те жататын мәліметтері статикалық типті объектіге бағытталған программалау тілдерінде компилятор егер класта шын мәнінде осындай әдіс бар болатынын анықтай алғанда ғана программалушы кластар әдісін шақыра алады. Мысал ретінде,программалаушы әр уақытта әр типті пішіндерден тұратын TGraphObject типті полиморфты айнымалыны анықтағысы келеді. Бұл полиморфты объектілер үшін қол жетімді.Дегенімен компилятор айнымалы үшін Draw әдісін қолдануға рұқсат етеді,егер де ол айнымалылар класында осындай әдәстің бар екеніне кепілдік берсе. Тіпті егер Draw әдісі TGraphObject класы үшін орындалмаса да, бұндай кепілдемені Draw әдісі TGraphObject класымен байланыс береді.
Әр пішін өзінше бейнелену үшін, Draw әдісі виртуалды болу керек.
2. Практикалық бөлім
1.Тапсырма
“Комплекстi санның” класын жасау. Енгізу және шығару, қосу операцияларын қайта жүктеу.
Бағдарлама мәтiнi
// Комплекстi сандар үшiн операцияларды шамадан тыс жүктеуге мысал
//класстың сипаттамасы
#include<iostream>
Using namespace std;
class complex
{
float Re, Im;
public:
complex();
complex(float Re, float Im);
complex operator+(complex);
friend ostream & operator<<(ostream & os, const complex & t);
friend istream & operator>>(istream & is, complex & t);
};
//функцияны іске асыру
complex::complex(){};//
complex::complex(float x, float y){Re=x;Im=y;};// параметрi бар конструктор
complex complex::operator+(complex a)
{complex
c; c.Re=a.Re+Re;c.Im=a.Im+Im;
ostream & operator<<(ostream & os,const complex & t)
{os<<t.Re<<””<<t.Im<<endle;};
istream &operator>>(istream & is,complex & t)
{cout<<”Re теріңіз”<<endl; is>>t.Re;
cout<<”Im теріңіз”<<endl; is>>t.Im;};
//Басты программа
main()
{
complex a(2,3), b(5,6),c;
cin>>c;cout<<c;
c=a+b; cout<<c;
system(“pause”);
}
2.Тапсырма
«Теңдеудiң түбiрi» (корень уравнение) жарияланған таза виртуалды функциясы бар абстрактiлi «Теңдеу» (уравнение) классын жасау. Мұрагерлік әдiспен базалық кластан “Сызықты теңдеу” және “Квадрат теңдеу” туынды классын құру керек. Әрбiр туынды класста «теңдеудiң түбiрi» (корень уравнение) функциясын жүзеге асыру керек (квадрат теңдеу үшін үлкен түбір қайтару қажет). Виртуалды функцияларды шақыруға мысал келтіретін Демонстрациялық программаны жазу.
Программа мәтіні
#include<iostream>
#include<cmath>
using namespace std;
class Equation
{
protected:
float a,b,c;
public:
Equation(float,float,float);
virtual float Root()=0;
};
Equation::Equation(float a1,float b1,float c1){a=a1;b=b1;c=c1;};
class Linear_Equation:public Equation
{
public:
Linear_Equation(float,float,
float Root();
};
//Функцияны іске асыру
Linear_Equation::Linear_
float Linear_Equation::Root(){cout<<
class Square_Equation:public Equation
{
public:
Square_Equation(float,float,
float Root();
};
//Функцияны іске асыру
Square_Equation::Square_
float Square_Equation::Root(){cout<< Квадраттық теңдеуді шешеміз”<<endl;
float d;d=b*b-4*a*c; return(-b+sqrt(d))/(2*a);};
//Басты Программа
main()
{
//Ерте байланыстыру
Linear_Equation x(2,2,8);
Square_Equation y(1,4,3);
cout<<x.Root()<<endl;
cout<<y.Root()<<endl;
//Кеш байланыстыру. Виртуалдық функцияларды шақыру
Equation *w;
w=&x;
cout<<w->Root()<<endl;
w=&y;
cout<<w->Root()<<endl;
system(“pause”);
}
3. Жеке тапсырма
Жалпы бөлім
Базалық абстрактілі классқа бірнеше туынды класс мұрагер болатындай класстар иерархиясын құру. Әр туынды класста параметрі бар конструктор құру керек. Әрбір туынды класста көрсетілген кестеге таза виртуалды функциясын жүзеге асыру. Әрбір туынды класс үшін енгізу операторларын, қорытынды операторларын және көрсетілген операцияны (кестедегі) қайта жүктеу. Қайта енгізу операторларын достық функциясы көмегімен жүктеу, ал операцияны кестеде корсетілген операцияларды операторлық функция көмегімен-класс мүшесін.
Виртуалды функциялардың шақыру мысалы келетіндей, демонстрациялық бағдарламаны жазу.
Вариант |
Базалық класс |
Туынды класс |
Виртуалды функция |
Жүктелген операция |
1 |
Фигура |
Квадрат,тікбұрыш,үшбұрыш |
аудан |
Көп |
2 |
Денесі |
Шар,куб,параллелепипед |
колем |
Аз |
3 |
Сандық объект |
Скаляр,екі өлшемді вектор,үш өлшемді |
модуль |
Көбейтінді(скаляр) |
4 |
Коп құрамдық |
а. а+b*x. a+b*x+c*x*x. a+b*x+c*x*x+c*x*x*x |
Козффициент суммасы |
Қосу |
5 |
Сандық объект |
Нақты сандар,комплекс сандар алгебралық формада |
модуль |
Көбейту |
6 |
Сандық объект |
Нақты сандар,комплекс сандар алгебралық формада |
модуль |
Бөлу |
7 |
Сандық объект |
Нақты сандар,комплекс сандар алгебралық формада |
модуль |
Көбейту |
8 |
Дұрыс Көпбұрыш |
Дұрыс үшбұрыш. Дұрыс төртбұрыш. Дұрыс бесбұрыш |
Ауданы |
Бөлу |
9 |
Көпмүше |
a. a+b*x. a+b*x+c*x^ a+b*x+c*x^+c*x3 |
Төртбұрыштар шамасының қосындысы. |
Азайту |
10 |
Пішін |
Шеңбер. Параллелограмм. Трапеция. |
Периметрі |
Тең |
000 |
Сандық Объект |
Нақты сан. Төртбұрыш матрица 2*2 |
Детерминант |
Көбейту |
Мысал: Жеке тапсырмаларды шешу.Нұсқа 000
Есептің қойылымы
Абстрактiлi негiздi класс жасау <<Cанмен көрсетілген объект>> таза виртуалды функция
<<Детерминант>>. Мұрагер болулар әдiсінің көмегімен негізгі класс туындысын құру
<<Нақты сан>> және <<төртбұрыш матрица 2*2>>. Әрбір туынды класында функцияны жүзеге асыру <<Детерминант>>. Әрбір туынды класын енгізу-шыгару операциясын қайта анықтап және операцияны көбейту керек.
Демонстрациялық программа жазып, виртуалды мысал келтіретін функция.
#include<iostream>
using namespace std;
class Number
{
public:
Number();
virtual float Determinant()=0;
};
class Real_Number:public Number
{
float a;
public:
Real_Number(float);Real_
Float Determinant();
Real_Number operator*(Real_Number);
friend ostream & operator <<(ostream & os,cons Real_Number & t);
friend istream & operator >>(istream & is,Real_Number & t);
};
class Matrix2:public Number
{
float a11, a12, a21, a22;
public:
Matrix2(float,float,float,
float Determinant();
Matrix2 operator*(Matrix2);
friend ostream & operator <<(ostream & os, const Matrix2&t);
friend istream & operator >>(istream & is, Matrix2 &t);
}
//Функцияны жүзеге асыру
Number : : Number(){};
Real_Number :: Real_Number(float a1) : Number() {a=a1;};
Real_Number :: Real_Number() : Number() {};
float Real_Number :: Determinant() {return a;};
Real_Number Real_Number :: operator*(Real_Number b)
{Real_Number c;
c.a=b.a*a;
return c;};
Matrix2 :: Matrix2(float x1, float x2, float x3, float x4) : Number()
{ a11=x1; a12=x2;a21=x3; a22=x4;};
float Matrix2 :: Determinant() {return (a11*a22-a12*a21);};
Matrix2 Matrix2 :: operator*(Mtrix2 b)
{Matrix2 c;
c.a11=a11*b.a11 + a12*b.a21; c.a12=a11*b.a12 + a12*b.a22;
c.a21=a21*b.a11 + a22*b.a21; c.a22=a21*b.a12 + a22*b.a22;
return c;
};
ostream & operator<<(ostream & so, const Real_Number & t)
{os<<”Real_Number : ” <<t.a<<endl; };
istream & operator>>(istream & is, Real_Number & t)
{cout<<”а-ны енгізіңіз ” <<endl; is>>t.a;};
ostream & operator <<(ostream & os, const Matrix2 & t)
{os << “Matrix2 :” <<t.a11<<” “<<t.a12<<” “<<t.a21<<” “<<t.a22<<endl;};
istream & operator >>(istream & is, Matrix2 & t)
{cout<<”а11-ды енгіз”<< endl; is>>t.a11;
cout<<”а12-ды енгіз”<< endl; is>>t.a12;
cout<<”а21-ды енгіз”<< endl; is>>t.a21;
cout<<”а22-ды енгіз”<< endl; is>>t.a22;
};
// Басты программа
main()
{
// ерте байланыстыру,
еңгізу-шығаруға шамадан тыс
Real_Number t; cin>>t; cout<<t ; cout<<t.Determinant()<<endl;
Matrix2 d; cin>>d;
cout<<d;cout<<d.Determinant()<
// кешірек баланыстыру
Number *x; ;
x= &t x ->Determinant();
x=&d;x->Determinant();
//Операцияны қайта жүктеу
Real_Number a(2),b(3);
cout<<a*b<<endl;
Matrix2 s(2,3,4,5),y(3,2,5,2),g;
Cout<<s*y<<endl;
System(“pause”);
}
4. Қосымша сұрақтар мен тапсырмалыр
1.Басқа операцияны қайта
2.Виртуалды
функцияны шақыруды нақты
3.Ерте және
кеш байланыстар арасындағы
4.Операторларды қайта жүктеу тәсілін өзгерту
5.Әдебиеттер
1.Шлидт Г.Полный справочник по C++.М.:Издательский дом<<Вильямс>>,2006,800 с.
Информация о работе Класстар. Полиморфизм. Виртуалды функциялар. Операторлардың шамадан тыс жүктелуi