10-мaвзу: Дўст функция вa дўст синфлaр
Download 59.01 Kb.
|
10-mavzu
10-мaвзу: Дўст функция вa дўст синфлaр Режа: 1. Конструктор; 2. Деструктор; 3. Муносабат турлари, дўстона (friend) функциялар; 4. Дўстона (friend) синфлар; 5. Синфнинг статик маълумотлари; 6. Объектлар массиви ва ундан фойдаланиш; 7. Кўрсаткичлар.
Конструкторлар бу синф компонента функциялари бўлиб, объектларни автоматик инициализация қилиш учун ишлатилади. Конструкторлар кўриниши қуйидагича бўлиши мумкин: Синф номи (формал параметрлар рўйхати)
Бу компонента функция номи синф номи билан бир хил бўлиши лозим. Мисол учун complex синфи учун конструкторни қуйидагича киритиш мумкин: complex (double re = 0.0; double im = 0.0 ) {real=re; imag=im;} Конструкторлар учун қайтарилувчи типлар, хатто void типи ҳам кўрсатилмайди. Дастурчи томонидан кўрсатилмаган ҳолда ҳам объект яратилганда конструктор автоматик равишда чақирилади. Масалан объект complex cc; шаклида аниқланган бўлса, конструктор автоматик чақирилиб, рreal ва imag параметрлари автоматик равишда 0.0 қийматларига эга бўлади. Кўзда тутилган ҳолда параметрсиз конструктор ва қуйидаги типдаги нусха олиш конструкторлари яратилади: T :: T (const T&) Мисол учун class F {... publir : F(const Т&) ... } Синфда бир нечта конструкторлар бўлиши мумкин, лекин уларнинг фақат биттасида параметрлар қийматлари олдиндан кўрсатилган бўлиши керак. Конструктор адресини ҳисоблаш мумкин эмас. Конструктор параметри сифатида ўз синфининг номини ишлатиш мумкин эмас, лекин бу номга кўрсаткичдан фойдаланиш мумкин. Конструкторни оддий компонента функция сифатида чақириб бўлмайди. Конструкторни икки хил шаклда чақириш мумкин : Синф_номи.Объект_номи (конструктор_хақиқий_параметлари) Синф_номи (конструктор_хақиқий_параметлари) Биринчи шакл ишлатилганда ҳақиқий параметрлар рўйхати бўш бўлмаслиги лозим. Бу шаклдан янги объект таърифланганда фойдаланилади: cоmplех СС(10.3; 0.22) // rеаl=10.3; SS.imag= 0.22; cоmplех ЕЕ (2.3) // ЕЕ . rеаl = 2.3; ЕЕ.imag = 0.0; cоmplех D() // хато Конструкторни иккинчи шаклда чақириш номсиз объект яратилишига олиб келади. Бу номсиз объектдан ifодаларда фойдаланиш мумкин. Мисол учун :
Бу таъриф орқали ZZ объект яратилиб, унга номсиз объект қийматлари (real= 4.0; imag= 5.0) берилади; Конструктор номи синф номи билан бир хил бўлиши лозимдир. Мисол учун сиз employee синфдан фойдалансангиз, конструктор ҳам employee номга эга бўлади. Aгар дастурда конструктор таърифи берилган бўлса объект яратилганда автоматик чақирилади. Қуйидаги дастурда employee номли синф киритилгандир:
Конструктор таърифи: employee:: employee (long empl_id, float empl) {
if (emplary < 50000.0) emplary = empl; else emplary = 0.0; } Шу синфдан фойдаланилган дастур: #include using namespace std; stdclass employee { public: employee(long, float); void show_employee(void); private: long employee_id; float emplary; }; employee::employee(long empl_id, float sal) { employee_id = empl_id; if (emplary < 50000.0) emplary = sal; else emplary = 0.0; } void employee::show_employee(void) { cout << "Nomer: " << employee_id <<endl; cout << "Maosh: " << emplary << endl; } int main() { employee worker(101, 10101.0); cout<<"ishchi"< worker.show_employee(); return 0; } Конструктордан фойдаланиб, объект таърифланганда параметр узатиш мумкин: employee worker(101, 10101.0); Aгар дастурда employee типидаги объектлар мавжуд бўлса ҳар бирини қуйидагича инициализация қилиш мумкин:
Конструкторлар ва кўзда тутилган қийматлар. Конструкторларда кўзда тутилган қийматлардан ҳам фойдаланиш мумкиндир. Мисол учун қуйидаги конструктор employee maoshi қийматини дастурда кўрсатилмаган бўлса 10000.0 тенг қилиб олади:
Объектлар массиви таърифлаш учун синф кўзда тутилган (параметрсиз) конструкторга эга бўлиши керак. Объектлар массиви кўзда тутилган конструктор томонидан, ёки ҳар бир элемент учун конструктор чақириш йўли билан инициализация қилиниши мумкин.
Қуйидаги мисолда player, синфи киритилади. Дастурда синф функцияси show_player ва конструктор ташқарисида таърифланади. Сўнгра player типидаги икки массив яратилиб, ҳар бири ҳақидаги маълумот экранга чиқарилади. #include #include using namespace std; class player { public: player(); player (string name,int weight, int age); void show_player (void); private: string name; int weight; int age; }; player::player() { name=""; weight = 0; age = 0; }; player::player(string name,int weight, int age) { player::name=name; player::weight = weight; player::age = age; }; void player::show_player (void) { cout<<"Ism: " << name << endl; cout<<"Vazn: " << weight << endl; cout<<"Yosh: " << age << endl; } class arryer_player {public: void show_arryer(player а[],int n) { for(int i=0;i<n;i++) {а[i].show_player();cout< void input_arryer(player а[],int n) {string name;int weight,age; for(int i=0; {cin>>name>>weight>>age; а[i]=player(name,weight,age); } } }; int main() {arryer_player аrr; Player happy[]={player("Olimov",58,24), player("Alimov",72,35)}; arr.show_arryer(happy,2); player matt[2]; arr.sinput_arryer(matt,2); arr.show_arryer(matt,2); return 0; } Инициализаторлар рўйхати. Конструктор ёрдамида объект маълумотларни инициялизациялашни иккита усули мавжуд. Биринчи усулда параметрлар қийматлари конструктор танасига узатилади. Икинчи усулда эса ушбу синфдаги инициализаторлар рўйхатидан фойдаланиш назарда тутилган. Бу рўйхат параметрлар рўйхати ва конструктор танаси орасига жойлашади. Рўйхатдаги ҳар бир инициализатор конкрет аниқ компонентага боғлиқ ва қуйидаги кўринишга эга: Синфнинг бирор объекти учун ажратилган хотира объект йўқотилгандан сўнг бўшатилиши лозимдир. Синфларнинг махсус компоненталари деструкторлар, бу вазифани автоматик бажариш имконини яратади. Деструкторни стандарт шакли қуйидагича: ~ sinf_nomi ( ) {destruktor tanasi} Деструктор параметри ёки қайтарилувчи қийматга эга бўлиши мумкин эмас (хатто void типидаги). Aгар синфда ошкор деструктор мавжуд бўлмаса, кўзда тутилган деструктор чақирилади. Дастур объектни ўчирганда деструктор автоматик чақирилади. Мисол:
Маълумотлар элементидан биргаликда фойдаланиш. Одатда, маълум синф объектлари яратилаётганда, ҳар бир объект ўз-ўзининг маълумотлар элементлари тўпламини олади. Бироқ шундай ҳоллар ҳам юзага келадики, унда бир хил синфлар объектларига бир ёки бир нечта маълумотлар элементларидан (статик маълумотлар элементларидан) биргаликда фойдаланиш керак бўлиб қолади. Бундай ҳолларда маълумотлар элементлари умумий ёки жузъий деб эълон қилинади, кейин эса тур олдиндан, қуйида кўрсатилганидек, static калит-сўз келади: private; static int shared_value; Синф эълон қилингач, элементни синфдан ташқаридаги глобал ўзгарувчи сифатида эълон қилиш керак. Бу қуйида шундай кўрсатилган: int class_name::shared_value; Навбатдаги дастур book_series синфини аниқлайди. Бу синф (seriya)нинг барча объектлари (kitoblari) учун бир хилда бўлган page_count элементидан биргаликда фойдаланади. Aгар дастур ушбу элемент қийматини ўзгартирса, бу ўзгариш шу ондаёқ барча синф объектларида ўз аксини топади: #include using namespace std; class book_series{ public: book_series(float); void show_book(void); void set_pages(int) ; private: static int page_count; float price; }; int book_series::page_count; void book_series::set_pages(int pages){ page_count = pages; } book_series::book_series(float price){ book_series::price = price; } void book_series:: show_book (void){ cout << "Narx: " << price << endl; cout << "Betlar: " << page_count << endl; } int main() { book_series programming(213.95); book_series word(19.95); word.set_pages(256); programming.show_book (); word.show_book() ; cout << endl << "page_count нинг ўзгариши " << endl; programming.set_pages(512); programming.show_book(); word.show_book(); return 0; } Кўриниб турганидек, синф page_count ни static int сифатида эълон қилади. Синфни аниқлагандан сўнг, дастур шу вақтнинг ўзиdа page_count элементини глобал ўзгарувчи сифатида эълон қилади. Дастур page_count элементини ўзгартирганда, ўзгариш шу вақтнинг ўзидаёқ book_series синфининг барча объектларида намоён бўлади. Aгар объектлар мавжуд бўлмаса, public static атрибутли элементлардан фойдаланиш. Синф элементини static каби эълон қилишда бу элемент ушбу синфнинг барча объектлари томонидан биргаликда қўлланади. Бироқ шундай вазиятлар юз бериши мумкинки, дастур ҳали объектни яратганича йўқ, аммо у элементдан фойдаланиши керак. Элементдан фойдаланиш учун дастур уни public ва static сифатида эълон қилиши керак. Малан, қуйидаги дастурда, хатто book_series синфидаги объектлар мавжуд бўлмаса ҳам, бу синфнинг page_count элементидан фойдаланилади:
Бу ўринда, синф page_count синфи элементини public сифатида эълон қилгани учун, хатто агар book_series синфидаги объектлар мавжуд бўлмаса ҳам, дастур синфнинг ушбу элементига мурожаат қилиши мумкин. Статик функция элементлардан фойдаланиш. Aвvalги дастур маълумотлар статик элементларининг қўлланишини кўрсатиб берган эди. C++ худди шундай усул билан статик функция-элементлар (усуллар)ни аниқлаш имконини беради. Aгар статик усул яратилаётган бўлса, дастур бундай усулни, хатто унинг объектлари яратилмаган ҳолда ҳам, чақириб олиши мумкин. Масалан, агар синф синфдан ташқари маълумотлар учун қўлланиши мумкин бўлган усулга эга бўлса, сиз бу усулни статик қила олишингиз мумкин бўларди. Функциядан фойдаланиш учун дастур уни public ва static сифатида эълон қилиши керак. Масалан, қуйидаги дастурда, хатто book_series сифатидаги объектлар мавжуд бўлмаса ҳам, бу синфнинг show_count() усулидан фойдаланилади:
Эълон қилиниши: stdclass myclass { friend int sum(myclass х); }; Aлбатта friend функциялар синфдан ташқарида мавжуд бўлади ва ушбу дўстона функция синфнинг барча соҳаларига мурожаат қила олиши мумкин. class sm{ int а, b; public: friend int sum(myclass х); void set_ab(int i, int j) { a = I; b = j; } }; int sum(myclass х) { return х.a+ х.b; //sum() ҳеч қайси classга тегишли эмас. } int main() { myclass n; n.set_ab(3, 4); cout << sum(n); return 0; } Дўстона (friend) синфлар Бир class бошқа бир class га дўст бўлиши мумкин. Бунда синфлар бир – бирининг аъзоларидан фойдаланиш имкониятига эга бўлади. Бунда шу нарсага эътибор бериш лозимки, бирор синфга дўст бўладиган синф (яъни friend калит сўзи орқали эълон қилинадиган синф), мазкур синфнинг аъзоларидан фойдаланиш имкониятини яратади. Эълон қилиниши: class myclass { friend someclass b; }; Дўст синфдан фойдаланиш учун қуйида мисол келтирилган. Бунда эътибор беришимиз лозимки, TwoValues синфи Min синфига дўст бўлиб, бунда Min синфи TwoValues синфининг аъзоларidан фойдаланиши мумкин. class TwoValues { int a, b; public: TwoValues(int i, int j) {а = i; b = j;} friend class Min; }; class Min { public: int min(TwoValues х) {return х.а < х.b ? х.a : х.b; } }; int main() { TwoValues ob(10, 20); Min m; cout << m.min(ob); return 0; } Синфнинг статик маълумотлари Class ўзгарувчисини static деб эълон қилинганда компилятор уни объектлар учун битта нусха кўринишidа яратади. Яъни бир нечта объект битта ўзгарувчидан фойдаланади. Static ўзгарувчи 0 га иницалиизация қилинади. Class static аъзоларига мурожат қилиш ClassName::static_member кўринишида мурожат қилинади, объект орқали ҳам мурожат қилса бўлади. Static ўзгарувчини static калит сўзи билан эълон қилинади. Эълон қилиш: class someclass { public: static int ob; }; Static майдонлардан фойдаланиш class Proper { public: static int ob_counter; }; int Proper::ob_counter; int main() { Proper а; cout< ob_counter++< cout<<a.ob_counter< return 0; } Static методлар Class методларини static ўзгарувчилар каби эълон қилса бўлади. Static методлар static аъзоларга мурожат қилади. Эълон қилиш: class someclass { public: static int ob; static int get_ob() {return ob;} }; Статик методлардан фойдаланиш class Proper { public: static int ob_counter; static int get_ob() {return ob_counter;} }; int Proper::ob_counter; int main() { cout< cout< return 0; } :: операторидан фойдаланиш Биз биламизки :: оператори class аъзоларига мурожат қилиш учун ишлатилади. Қуйидаги ҳолат берилган: int i; void f() { int i; i = 10; } int main() { f(); cout<<i; return 0; } :: оператори орқали глoбал ўзгарувчига мурожат қилиш қуйидагича амалга оширилади. int i; void f() { int i; ::i = 10; } int main() { f(); cout< return 0; } Объектларни функцияга юбориш Oбъектларни функцияга юбориш оддий ўзгарувчиларни юборган каби амалга оширилади.
Мисол асосида кўриб ўтамиз class Sum { int a, b; public: int plus() { cout<b;} void set_nums(int х, int y) {a = х; b = y;} }; void f(Sum x) { // а объекти х oбъектига нусха олинди х.set_nums(4,5); х.plus(); } int main() { Sum а; f(а); // а oбъекти f() функциясига юборилди а.set_ nums(3,2); а. plus (); return 0; } Функция oбъект қайтаради Функция oбъект қайтариши учун қайтариладиган oбъектнинг тоифаси функциянинг қайтариш типига кўрсатилиши керак. Мисол:
Мисол
class Sum {int a, b; public: int plus() { cout<b;} void set_nums(int x, int y) { a = x; b = y; } }; Sum f() {x.set_nums(4,5); return x; // Функция Sum тоифадаги oбъект қайтаради} int main() {Sum a;a = f(); // а oбъектга f() дан қайтган oбъект ўзлаштирилди а.plus(); return 0; } Oбъектларни ўзлаштириш stdclass Sum {int a, b; public: int plus() { cout<b;} void set_nums(int x, int y) { a = x; b = y; } }; int main() { Sum a , b; а.set_nums(3,2); b = a; // a oбъект b oбъектга ўзлаштирилди b.plus(); return 0; } Кўрсаткичлар Oбъектларга кўрсаткич (pointer) Oбъектга йўналтирилган дастурлашда синфлар орқали oбъектлар устида турли хил бажариладиган амаллар мавжуд. Oбъектларга бошқа ўзгарвчилар каби кўрсаткич орқали мурожаат қилиш мумкин. Oбъект аъзоларига кўрсаткич орқали мурожат қилиш учун .(нуқта) ўрнига – > оператори ишлатилади. Қуйида мисол келтирилган: class c1 { int а; public: int get_num() {return а;} c1(int х){ а = х; } }; c1 а = 2, *p, b[2]; // p кўрсаткич эълон қилинди p = &a; // а oбъектнинг адреси п кўрсаткичга олинди p – >get_num(); // кўрсаткич орқали oбъект аъзосига мурожат p = b ; // b oбъектнинг 1 чи элементи адреси p кўрсаткичга олинди Кўрсаткичларда бажариладиган +, – амалларни oбъектлар билан ҳам қўллаш имконияти мавжуд бўлиб, оддий кўрсаткичлардаги барча хусусиятлар ушбу ҳолатда қўлланилиш жараёнида ҳам тўлиқ сақланиб қолади. class c1 {int а; public: int get_num() {return а;} c1(int х){ а = х; } }; c1 а[3] = {1,2,3}, *p; p = а; // а oбъектнинг 1-адреси п кўрсаткичга олинди p->get_num (); // output 1 p++; // p кейинги oбъектни кўрсатади p – >get_num(); // output 2 Oбъект массивига кўрсаткич қуйидагича мисол орқали амалга оширилади. Бунда c1 синф типида а oбъект массиви эълон қилинган ва p синф типидаги кўрсаткичга oбъект массиви ўзлаштирилган. class c1{int а; public: int get_num() { return а;} c1(int х){а = х;} }; int main() {c1 а[3]={1,2,3}; c1 *p; p=а; for(int i=0; i<3; i++) cout<<(p+i)->get_num(); return 0;} Oбъект аъзоларини кўрсаткичга олиш class c1 {public:int а; int get_num() {return а;} c1(int х){а = х;} }; c1 b = 4; int *p; p = &b.a; // c1.а нинг адреси p кўрсаткичга олинди *p = 8; // b.a нинг қиймати 8 га ўзгартирилди cout< this кўрсаткичи this жорий oбъектга кўрсаткич. class c1 {int а; public: int get_num() { return this ->a;} c1(int а){ this ->a = a; } }; c1 b = 4; cout< Насл олинган тоифага кўрсаткич Бир тоифадаги кўрсаткич бошқа бир oбъект тоифага кўрсата олмайди. Фақатгина бир ҳолат истисно. Бу она class ворис class ларга кўрсаткич бўла олади. class base { int а; public: int get_a() { return this ->a;} void set_а(int х){this ->a = х; } }; class derived: public base {int b; public: int get_b() { return this ->b;} void set_b(int х){ this ->b = х; }};
base *bp; // она bp кўрсаткич derived d; // ворис d oбъект bp = &d; // base кўрсаткич derived га кўрсатади //derived oбъектига base кўрсаткич орқали мурожат bp->set_а(5); cout<<bp->get_а(); // errorrrr, чунки bp base pointер орқали derived oбъектнинг аъзоларига мурожат қила олмаймиз bp->set_b(5); //derived oбъектнинг аъзоларига мурожат қилиш учун bp base кўрсаткични derived кўрсаткич тоифасига ўзгартириш керак ((derived*)bp)->set_b(10); cout<<((derived*)bp)->get_b(); Синф аъзоларига кўрсаткич C++ да шундай кўрсаткич қилса бўладику бу кўрсаткич class аъзосини кўрсатиб туради. Бундай кўрсаткичларни pointер- to - member деб аталади. Class аъзосига кўрсаткичда махсус .* ва ->* операторлар ишлатилади. Эълон қилиниши: int c1::*data; //тоифага кўрсаткич int (c1::*func)(); //функцияга кўрсаткич data = &c1::val; //val жойини data га олиш func = &c1::get_num; //get_num жойини func га олиш ob.*data; // val га мурожат (ob.*func)(); // get_num() га мурожат Демак юқоридаги мисолдан кўриниб турибдики, oбъект кўрсаткичи орқали синф аъзоларига мурожаат қилиш имконияти мавжуд. Бунда синф аъзосига мос кўрсаткич ўзгарувчи эълон қилинади ва ушбу ўзгарувчи орқали синф аъзосига мурожаат қилинади. stdclass c1 { public:int get_num() { return val + val; } c1(int а){ val = а; } int val; }; int c1::*data; // c1 stdclass аъзоларига кўрсаткич яратилди int (c1::*func)(); // c1 stdclass аъзоларига кўрсаткич яратилди c1 а(4), b(8); // а ва б oбъектлар яратилди data = &c1::val; // data ва func кўрсаткичларига c1 аъзоларининг жойлари олинди func = &c1::get_num; // data ва func кўрсаткичларига c1 аъзоларининг жойлари олинди cout<<а.*data<<и.*data< қилинмоқда cout<<(а.*func)();<<(b.*func)(); // Oбъект аъзоларига кўрсаткичлар орқали мурожат қилинмоқда Oбъектга кўрсаткич бўлган ҳолат stdclass c1 { public: int get_num() { return val + val; } c1(int а){ val = а; } int val; }; int c1::*data; int (c1::*func)(); c1 а(4), *p; //a ва b oбъектлар яратилди p = &a;// p га a oбъектнинг адреси олинди data = &c1::val; func = &c1::get_num; cout< *data< cout<<(p – >*func)(); 1. Синфлар ва oбъектлар тушунчаси. 2. Синф хусусиятлари ва методлари.
3. Синф элементларига мурожаат ҳуқуқлари. 4. Конструктор нима.
5. Конструкторлар хосsalарини кўрсатинг. 6. Конструктор нима учун типсиз эълон қилинади?
7. Деструкторни мисоллар ёрдамида тушунтиринг. 8. Конструкторни деструктордан нима ажратиб туради?
9. Oбъектлар массивларини тушунтиринг. 10. Синф статик хусусият ва методлари.
11. Oбъектларга кўрсаткич қандай яратилади 12. Оддий синф билан насл олинган синфга кўрсаткич қандай фарқланади?
13. Насл олинган тоифага кўрсаткич нима? 14. Илоvalар (референcе) нима?
15. Синф аъзоларига кўрсаткич? 16. This кўрсаткичидан фойдаланиш?
17. Дўст функциялар қандай эълон қилинади? 18. Дўст синфлар қандай эълон қилинади?
19. Oбъектлар массиви қандай эълон қилинади? 20. :: операторidан фойдаланиш
21. Oбъектларни ўзлаштириш 22. Oбъектлар массивини иниsalизация қилиш
23. Инлине функция ва оддий функциянинг нима фарқи бор? 24. Синф ичидаги инлине функциялар
25. Aгарда синфнинг иккита oбъектини эълон қилсак, уларнинг о‗згарувчи аъзолари қиймати турлича бўлиши мумкинми? Download 59.01 Kb. Do'stlaringiz bilan baham: |
ma'muriyatiga murojaat qiling