Автор: Пользователь скрыл имя, 11 Февраля 2013 в 11:06, лекция
С++ тілінің базалық жабдықтары. Программа құрылымы. Жиымдар
Қарастырылатын сұрақтар:
1. С++ тілінің базалық жабдықтары
2. Мәліметтер типі
3. Программа құрылымы
4. Айнымалылар мен өрнектер
5. Тармақталу, басқаруды беру операторлары және циклдік операторлар
6. Жиымдар (массивтер)
cout<<"SIZEOF TBL=="<<sizeof(t1)<<endl;
// ...
cout<<"N=="<<Tbl::getN()<<
return 0;
}
int Tbl::N=0;
int main() {
Tbl t1("Time"), t2(8), t3;
cout<<"SIZEOF TBL=="<<sizeof(t1)<<endl;
// ...
cout<<"N=="<<Tbl::getN()<<
return 0;
}
Нәтижесі:
SIZEOF TBL==12
. . .
SZ==5 LEN==4 NAME="Time" ptr==770920
N==4
delete sz==5 len==4
This нұсқауышы
Әр шақыру кезінде әрбір функция-мүше тағы бір параметр алады. Ол
Мысалы: Tbl класының объектілерінен бір байланысты тізімді тұрғызу үшін this қолдану.
class Tbl {
public:
// ...
void add(){this->next=top; top=this;}// тізім басына элем. қосу ф-ясы
void lprint(); // тізім элементерін тізб. басып шығару ф-ясы
private:
// ...
Tbl* next;
static Tbl *top;
};
void Tbl::lprint() {
if (!top) cerr<<"List is empty\n";
else {
Tbl *temp=top;
while(temp) { cout<<temp->name; temp=temp->next; }
cout<<endl;
}
}
int Tbl::N=0;
Tbl* Tbl::top=0;
int main() {
Tbl t("Time "), i("is "), m("money.");
i.lprint();
m.add(); i.add(); t.add();
i.lprint();
return 0;
}
Нәтижесі:
List is empty
Time is money.
delete sz==7 len==6
Класстың достық функциялары
Класстың достық функциялары- бұл класстың қорғалған (protected) және жабық (private) бөліктеріне енуді қамтамасыз ететін, бірақ берілген класстың мүшесі болып табылмайтын функциялар.
Достық функциялар friend түйінді сөзінің көмегімен класстың кез-келген бөлігінде хабарланады.
Достық функциялар классты анықтаудың сыртында анықталуы тиіс: көрінудің ауқымды аймағында немесе басқа класста.
Достық функциялар бірден бірнеше классқа дос болуы мүмкін.
Мысалы: Екі қатарды байланыстыру үшін арналған Tbl класының достық функциясы
Tbl класының анықталуы
#include <iostream.h>
#include <string.h>
class Tbl {
public:
//...
private:
friend void cat(Tbl&, Tbl&); // прототип-хабарлау
char *name;
int sz, len;
};
void cat(Tbl& u, Tbl& v) {// класс сыртында cat() анықтау
if (u.sz>u.len+v.len) {
strcat(u.name,v.name);
u.len = u.len+v.len;
}
else {
char *temp = new char [u.len+v.len+1];
strcpy(temp,u.name);
strcat(temp,v.name);
delete [] u.name;
u.name = temp;
u.sz = u.len+v.len+1;
u.len = u.len+v.len;
}
}
cat() қолдану:
int main() {
Tbl t1("Game"),t2(" over!");
t1.print();
t2.print();
cat(t1,t2);
t1.print();
t2.print();
return 0;
}
Нәтижесі.
SZ==5 LEN==4 NAME="Game" ptr==770870
SZ==7 LEN==6 NAME=" over!" ptr==7708a0
SZ==11 LEN==10 NAME="Game over!" ptr==7708d0
SZ==7 LEN==6 NAME=" over!" ptr==7708a0
delete sz==7 len==6
delete sz==11 len==10
Шаблондар.
Шаблондар класстар мен функциялардың шексіз туыстарын (родственные) құруға мүмкіндік береді. Шаблон мәліметтер типінің параметрі ретінде қолданылады.
Функция шаблонын анықтау синтаксисі
template <шаблон_параметрлерінің_
Класс шаблонын анықтау синтаксисі:
template <шаблон_параметрлерінің_
Шаблон немесе шаблон аргументі бойынша функцияны немесе/және класстарды хабрлауды құру үрдісі шаблонның инстанцированиесі деп аталады.
Мысалы: Функциялар шаблоны: квадраттау және екі айнымалының мәндерін алмастыру
template <class T> T sqr(T val) { // T – бұл шаблон параметрінің типі
return val*val;
}
template <class T> void swap(T& a, T& b) {
T temp=a;
a=b;
b=temp;
}
int main() {
int a=10, b=20;
cout<<"Before: "<<"a=="<<a<<" b=="<<b<<endl;
swap(a,b); // swap<int>(int, int)шақырылатын болады
cout<<"After: "<<"a=="<<a<<" b=="<<b<<" a^2=="<<sqr(a)<<endl; // int sqr<int>(int)
double da=acos(-1.), db=exp(0.5);
cout.precision(15); // баспа кезінде цифрлар санын береміз
cout<<"Before: "<<"da=="<<da<<" db=="<<db<<endl;
swap(da,db); // swap<double>(double, double) шақырылады
cout<<"After: "<<"da=="<<da<<" db=="<<db<<" da^2=="
<<sqr(da)<<endl; // double sqr<double>(double)
return 0;}
Нәтижесі:
Before: a==10 b==20
After: a==20 b==10 a^2==400
Before: da==3.14159265358979 db==1.64872127070013
After: da==1.64872127070013 db==3.14159265358979 da^2==2.71828182845905
Мысалы: MyComplex шаблонын қолдану
int main() {
MyComplex<double> re1(acos(-1.)/2), im1(0,1);
cout<<"Before: "<<"re1=="<<re1<<" im1=="<<im1<<endl;
swap(re1,im1); // Шақырылады:
// swap<MyComplex<double>>(
cout<<"After: "<<"re1=="<<re1<<" im1=="<<im1<<endl;
MyComplex<int> ci12(1,2), ci(sqrt(2.)); // Бұл жерде ескеру аласыздар
cout<<"Before: "<<"ci12=="<<ci12<<" ci=="<<ci<<endl;
swap(ci12,ci); // шақырылады:
// swap<MyComplex<int>>(
cout<<"After: "<<"ci12=="<<ci12<<" ci=="<<ci<<endl;
return 0;
}
Нәтижесі:
Before: re1== (1.5707963267949, 0) im1== (0, 1)
After: re1== (0, 1) im1== (1.5707963267949, 0)
Before: ci12== (1, 2) ci== (1, 0)
After: ci12== (1, 0) ci== (1, 2)
Мысалы: Бір байланысты тізімнің түсінігін қалыптастырушы шаблон
template<class C> class List1 {// C – шаблон параметрінің типі
struct ListItem {//тізім элементінің типін анықтаймыз
C info; // қажет ақпарат
ListItem* next;
ListItem(const C& t, ListItem* n):info(t),next(n){} // У эл-та свой к.
};
ListItem *top;
List1(const List1&); // көшіруге шек қою
List1& operator=(const List1&); // меншіктеуге де
public:
List1(const C& t):top(new ListItem(t,0)) {} // Конструктор
void add2top(const C& t) {// тізім басына элементті қосу ф-ясы
ListItem *temp=new ListItem(t,top);
top=temp;
}
void print_list(){// тізім элементтерін басып шығару
for (ListItem* p=top; p; p=p->next)
cout<<p->info; // С типі үшін << операторы анықталуы керек
}
~List1() {// Деструктор
for (ListItem* p=top; p; ) {
ListItem *pt=p;
p=p->next;
delete pt;
}}};
мысалы: List1 шаблонын қолдану.
#include "Tbl.h" // Tbl класының хабарлануын енгізу
int Tbl::N=0;
int main() {
MyComplex<double> re1(acos(-1.)/2), im1(0,1);
typedef MyComplex<double> complex_double; // MyComplex<double> синоним атын беру
List1<complex_double> ld(re1); // комплекс сандардан тізім құрамыз
ld.add2top(im1);
ld.print_list();
cout<<endl;
// Tbl класының объектілерінен тізім құру
Tbl begin("Time"), median(" is"), end(" money.");
List1<Tbl> lt(end);
lt.add2top(median);
lt.add2top(begin);
lt.print_list();
cout<<endl;
return 0;
}
Нәтижесі
(1.5707963267949, 0) (0, 1)
N== 6 SZ==5 LEN==4 NAME=="Time"430e70
N== 6 SZ==4 LEN==3 NAME==" is"430e00
N== 6 SZ==8 LEN==7 NAME==" money."430d90
6лекция
Ассоциативті контейнерлердің типтері
Ассоциативті контейнерлер
Ассоциативті контейнерлер жылдам енуді қамтамасыз етеді, олар іздеу бұтағы негізінде тұрғызылады.
Ассоциативті контейнердің бес типі бар: сөздіктер (map), көшірме сөздіктер (multimap), жиын (set), көшірме жиын (multiset), биттік жиындар (bitset).
Сөздік қос мән негізінде тұрғызылған, алғашқысы – элементтер идентификаторына арналған түйін, екіншісі- элементтің өзі.
Мысалы: ағылшын-орыс сөздігінде түйін- ағылшын сөзі, ал элемент –орыс сөзі.
Ассоциативті контейнерлер <map>, <set>тақырыптық файлдарда сипатталады.
pair шаблонының екі параметрі бар, бірінші -first, екінші –second.
Екі конструктор анықтылған: бірі элементтерді инициализациялау үшін, ал екіншісі көшіру конструкторы.
Үндеместік бойынша конструкторы жоқ, яғни объектіні құру кезінде мәнге меншіктеу керек.
Сөздіктер
Сөздіктер (map) барлық түйіндер ерекше болуы керек. Сөздіктегі элементер сұрыпталған түрде сақталынады, сондықтан түйіндер “кіші” қатынасымен анықталады.
Сөздік шаблоны үш параметрден тұрады: түйін типі, элементтипі, функционалды объектнің типі (“кіші” қатынасымен анықтаушы):
template < class Key, class T, class Compare= less<Key>>
class map {
public:
typedef pair < const Key, T> value_type;
explicit map(const compare&comp=Compare());
template < class InputIter>
map (InputIter first, InputIter last, const compare&comp=Compare());
map (const map<Key, T, Compare>&x);
….. };
Бірінші конструктор функционалды объектіні қолданып, бос сөздікті құрады.
Екінші конструктор сөздікті құрады және оған итератор диапазонымен анықталған элементтерді жазады.
Үшінші конструктор көшіру конструкторы болып табылады.
Басқа контейнерлер үшін сияқты сөздік үшін де деструктор, меншіктеу операциясы, қатынас операциясы анықталған.
Түйін бойынша элементке ену үшін [] операциясы анықталған:
T&operator [] (const Key&x);
Бұл операцияның көмегімен элементтер мәндерін ғана алып қоймай, сонымен қатар сөздікке жаңасын да қосуға болады.
Мысалы: Телефон кітапшасын қарастырайық, түйіні– аты-жөні, элементі- телефон нөмірі.
#include <fstream>
#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef map <string, long, less <string>> map_s1;
int main ()
{ map_s1 m1;
ifstream in (“phonebook”);
string str;
long num;
while (in>>num, !ineof ())
{
in. get (); // бос орынды қалдыру
getline (in, str); // аты-жөнін оқу
m1[str]=num; // сөздікке енгізу
cout<<str<<” “<<num<<endl;
}
m1[“Asel”]=2234242; // сөздікті толықтыру
map_s1:: iterator i;
cout<<”m1: “<<endl; // сөздікті шығару
for (i=m1.begin(); i!=m1.end();i++)
cout<<(*i).first<<" "<<(*i).second<<endl;
i=m1.begin();i++; //екінші элементті шығару
cout<<" 2-shi elementti shygaru: ";
cout<<(*i).first<<" "<<(*i).second<<endl;
cout<<" Aset"<<m1["Aset"]<<endl; // түйін бойынша элементті шығару
return 0; }
Сөздік:
2434343 Temirlan
2393939 Anuar
2555555 Asem
2445566 Aset
Нәтижесі:
m1: Anuar 2393939
Asel 2234242
Asem 2555555
Aset 2445566
Temirlan 2434343
Екінші элемент: Asel 2234242
Aset 2445566
Сөздіктегі элементтерді іздеу үшін төмендегі функциялар анықталған:
iterator find (const key_type&x);
const_iterator find (const key_type&x) const;
const_iterator lower(const key_type&x) const;
const_iterator upper (const key_type&x) const;
size_type count (const key_type&x) const);
Элементтерді қосу және жою үшін мына функциялар анықталған:
pair <iterator, bool> insert (const value_type&x);
iterator insert (iterator position, const value_type&x);
template < class InputIter>
void insert
void erase
void clear ();
7лекция
Мұрагерлік. Виртуалды функциялар. Ағымдық класстар
Қарастырылатын сұрақтар:
1. Мұрагерлік
Объектілі-бағытталған
программалаудың негізгі
class A {
public:
A();
~A();
MethodA();};
class B : public A {public:
B(); . . .};
«Мұрагерлік" термині В класы А класының барлық қасиеттеріне ие дегенді білдіреді, яғни мұрагерлікке алды. Туынды класстың объектілері базалық класстың барлық атрибуттары мен функцияларына ие. Сонымен қатар жаңа класс өз атрибуттары мен функцияларын қоса алады. Туынды класс басқа класстар үшін базалық бола алады. Мұрагерліктің қатынастарын бейнелей отырып, оларды бұтақ түрінде немесе иерархия түрінде береді.
Егер туынды класстың тек бір ғана базалық класы (ата-анасы - родители) болатын болса, онда мұрагерлік жай мұрагерлік деп аталады.
Егер туынды класстың
бірнеше базалық класстары
2. Туынды классты тұрғызу
Қандай да бір фирмада қызмет ететін қызметкерлерге қатысты программа құруды қарастырайық. Бұл программаның мәліметтер құрылымы мына түрде болады:
class employee { // қызметкер
char* name; // аты-жөні
short age; // жасы
short department; // бөлімі
int salary; //
employee* next;
// ...
};
Басқа қызметкерлердің сәйкес тізімі next өрісі арқылы байланысады. Енді менеджерді анықтайық:
class manager { // менеджер
employee emp; // қызметкер ретінде менеджер туралы жазба
employee* group; // қарамағындағы адамдар
// ... };
Менеджер де қызметкер болып табылады; employee қатысты мәліметтер manager объектісінің emp мүшесінде сақталынады.
manager класы employee класы үшін туынды класс болып табылады және керісінше, employee класы manager үшін базалық класс болып табылады. manager класы group мүшесіне қосымша employee (name, age и т.д.) класының мүшелерінен де тұрады. employee и manager класын анықтап алғаннан кейін, қызметкерлер тізімін құруымызға болады. Олардың кейбіреуі менеджердің құрамыгна кіреді.
Мысалы:
void f() {
manager m1, m2;
employee e1, e2;
employee* elist; elist = &m1; // elist –қа m1, e1, m2 және e2 орналастыру
m1.next = &e1;
e1.next = &m2;
m2.next = &e2;
e2.next = 0; }
Менеджер қызметкер болғандықтан,
manager* employee* ретінде қолдануға болады. Бірақ
қызметкер менеджер болмауы да мүмкін,
сондықтан employee* manager* ретінде қолдануға
болмайды.
employee және manager үшін қолданылатын функцияларды қарастырайық.
Мысалы: class employee {
char* name;
// ...
public:
employee* next;
void print(); // ... };
class manager : public employee
{ // ...
public:
void print();
// ... };
Әрбір қызметкер жайлы ақпаратты шығаратын функцияны қарастырайық:
void print_employee(employee* e)
{ switch (e->type)
{ case E: cout << e->name << "\t" << e->department << "\n";
// ... break;
case M: cout << e->name << "\t" << e->department << "\n";
// ...
manager* p = (manager*)e;
cout << " деңгейі " << p->level << "\n"; // ... break; } }
Әрбір қызметкер өзінің типіне сәйкес шығарылады.
Мысалы:
main() { employee e; e.name = «Айман"; e.department = «Бухгалтерия";
e.next = 0;
manager m;
m.name = «Фарида";
e.department = «Менеджер";
m.level = 2;
m.next = &e; f(&m); }
3. Виртуалды функциялар.
Егер класстың ең болмағанда бір виртуалды функциясы болса, онда ол класс абстрактілі класс деп аталады.
Виртуалды функциялар төмендегідей хабарланады:
class className1
{
// функция-мүшелер
virtual returnType functionName(<параметрлер тізімі>);