1-tajriba ishi Mavzu: Tiplarni dinamik tarzda aniqlash. Tiplarni almashtirish operatorlari Ishdan maqsad



Download 62,5 Kb.
bet1/3
Sana01.06.2023
Hajmi62,5 Kb.
#947557
  1   2   3
Bog'liq
1-Amaliyot


1-tajriba ishi
Mavzu:Tiplarni dinamik tarzda aniqlash. Tiplarni almashtirish operatorlari
Ishdan maqsad: C++ dasturlash tilida tiplarni dinamik tarzda aniqlash va almashtirish operatorlarini o’rganish.
Nazariy qism
Operator dynamic_cast
Operator dynamic_cast dastur davomida polimorf turlarini olib kelish jarayonini amalga oshiradi.
Ehtimol, yangi operatorlarning eng muhimi dynamic_cast turlarini dinamik ravishda olib kelish operatori. Dasturni amalga oshirish vaqtida u tavsiya etilgan operatsiyaning haqiqiyligini tekshiradi. Agar uning chaqiruvi vaqtida berilgan operatsiya qabul qilinishi mumkin bo'lmasa, turlarni olib tashlash amalga oshirilmaydi. Dynamic_cast operatorining umumiy shakli quyidagicha.
dynamic_cast (expr)
Bu erda type elementi ushbu operatsiyani bajarish maqsadi bo'lgan yangi turni anglatadi va expr elementi bu yangi turga olib keladigan ifodasidir. Turi bir ko'rsatgich yoki link bilan taqdim etilishi kerak, va ifoda expr bir pointer yoki havola berilishi kerak. Shunday qilib, dynamic_cast operatori bir turdagi markerni boshqa ko'rsatgichga aylantirish yoki bir turdagi havolani boshqasiga havola qilish uchun ishlatilishi mumkin.

Bu operator asosan polimorf turlari orasida turi olib operatsiyalar dinamik bajarish uchun ishlatiladi. Misol uchun, agar polimorf sinf b va D berilgan bo'lsa, va sinf D sinf b olingan, keyin operator yordamida dynamic_cast har doim markerni aylantirish mumkin D* a pointer uchun*, asosiy sinf uchun pointer har doim sinf ob'ektini ko'rsatish uchun foydalanish mumkin, chunki, asosiy olingan. Biroq, operator dynamic_cast a pointer aylantirish mumkin * a pointer d * faqat holda, manzil ob'ekt, albatta, sinf ob'ekti D bo'lsa. Va, umuman, operator dynamic_cast faqat sharti bilan muvaffaqiyatli amalga oshiriladi, agar ruxsat polimorf haydash turlari bo'lsa, t. e. a pointer bo'lsa (yoki link), yangi turiga gijgijlash, ishora mumkin (yoki mos yozuvlar) bu yangi turdagi ob'ektga yoki ob'ekt, undan olingan. Aks holda, t. u. agar berilgan turdagi operatsiyalar bajarilmasa, dynamic_cast operatorining harakati natijasi nolga teng deb hisoblanadi, agar bu operatsiyada ko'rsatgichlar ishtirok etsa. (Agar ushbu operatsiyani bajarishga urinish muvaffaqiyatsiz bo'lsa, unda bog'lanishlar mavjud bo'lsa, bad_cast tipidagi istisno hosil bo'ladi.)


Oddiy misolni ko'rib chiqaylik. Base klassi polimorf deb hisoblang va Derived klassi base sinfidan chiqariladi.


Base *bp, b_ob;
Derived *dp, d_ob;
bp = & d_ob; / / asosiy sinf uchun pointer sinf Derived ob'ektini ko'rsatadi.
dp = dynamic_cast (bp); / / lotin sinfiga ishora qilish mumkin.
agar (dp) cout <<””;

Bu erda ko'rsatkich bp olib (tayanch sinf uchun) ko'rsatkich dp uchun (lotin sinf uchun) muvaffaqiyatli amalga, bp, albatta, sinf ob'ektini bildiradi, chunki Derived. Shuning uchun, kodning ushbu qismini bajarayotganda, Add turi muvaffaqiyatli bo'ladi!. Ammo kodning keyingi qismida bunday turdagi operatsiyani amalga oshirishga urinish muvaffaqiyatsiz bo'ladi, chunki bp aslida base sinfining ob'ektiga ishora qiladi va agar u ularga yuborilgan ob'ekt aslida lotin sinfining ob'ekti bo'lmasa, asosiy sinfga indeksni lotin turiga olib kelish noto'g'ri.




bp = & b_ob; / * asosiy sinf uchun pointer sinf Base ob'ektini anglatadi. */
dp = dynamic_cast (bp); / / xato!
if(!dp) cout <<””;

Turi olib kelish jarayonini amalga oshirishga urinish muvaffaqiyatsiz bo'lgani uchun, ushbu kod parchasini bajarayotganda xabar ko'rsatiladi Adjust turi bajarilmadi.


Quyidagi dastur dynamic_cast operatorining turli xil holatlarini namoyish etadi.


// Dynamic_cast operatoridan foydalanish.
#include
using namespace std;
class Base {
public:
//bu bizning bemorlarimiz va xodimlarimiz uchun katta sharaf.\n"; }
// . . .
};

class Derived : public Base {


public:

barcha huquqlar himoyalangan\n"; }

};


int main()

{


Base *bp, b_ob;

Derived *dp, d_ob;


dp = dynamic_cast (&d_ob);


if(dp) {

cout < < "turlari olib" < *)

amalga oshirildi.\n";


dp->f();

}

boshqa cout <";


cout << endl;


bp = dynamic_cast (&d_ob);


if(bp) {

cout < < "turlari olib" < *)

amalga oshirildi.\n";


bp->f();

}

boshqa cout <";


cout << endl;


bp = dynamic_cast (&b_ob);


if(bp) {

cout < < "turlari olib" < *)

amalga oshirildi.\n";


bp->f();

}

boshqa cout <";


cout << endl;


dp = dynamic_cast (&b_ob);


agar (dp) cout <";


else

cout < < "turlari olib" <\n";

cout << endl;


bp = & d_ob; / / bp Derived sinfining ob'ektini ko'rsatadi


dp = dynamic_cast (bp);


if(dp) {

cout < < "BP ning Derived *\n turiga olib kelishi" < < "bp haqiqatdan ham\n" <

Derived.\n";


dp->f();

}

boshqa cout <";


cout << endl;


bp = & b_ob; / / br base sinf ob'ektini bildiradi


dp = dynamic_cast (bp);


agar (dp) cout <";


else {

cout < < "endi bp ning Derived *\n turiga olib kelishi" <<"bp\n" < < "aslida \ n ob'ektiga ishora qiladi" <\n";

}


cout << endl;

dp = &d_ob; / / dp Derived sinf ob'ektini bildiradi


bp = dynamic_cast (dp);


if(bp) {

cout <\n";

bp->f();

}

boshqa cout <";


return 0;


}


Dastur bunday natijalarni ishlab chiqaradi.

Turlari (Derived * dan Derived * ga) olib kelish amalga oshiriladi.


Derived sinfida.


Turlarni olib kelish (Derived* dan base* ga) amalga oshiriladi.


Derived sinfida.


Turlari (base * dan base* ga) olib kelish amalga oshiriladi.


Base sinfida.


Turlarni olib kelish( base * dan Derived * ga) amalga oshirilmaydi.


Brni derived * turiga olib kelish, chunki br, albatta, Derived sinfining ob'ektiga ishora qiladi.


Derived sinfida.


Endi brni Derived* turiga olib kelish amalga oshirilmaydi, chunki br aslida base sinfining ob'ektini ko'rsatadi.


Dp turini base * ga olib kelish amalga oshirildi.


Derived sinfida.


Operator dynamic_cast ba'zan operator typeid o'rniga foydalanish mumkin. Misol uchun, deylik, sinf Base — polimorf va sinf Derived uchun asosiy, keyin kod keyingi bo'lagini amalga qachon ko'rsatkich dp ob'ekt manzilini beriladi, pointer BP nomiga, lekin faqat holda, bu ob'ekt, albatta, sinf Derived ob'ekti bo'lsa.


Base *bp;


Derived *dp;


// . . .

if(typeid(*bp) == typeid(Derived)) dp = (Derived *) bp;

Bunday holda, odatdagi olib tashlash operatsiyalari qo'llaniladi. Bu erda juda xavfsiz, chunki if ko'rsatmasi typeid operatori yordamida turlarni olib kelish operatsiyasining qonuniyligini haqiqiy bajarilishidan oldin tekshiradi. Xuddi shu narsa operator tomonidan typeid operatorlari va if ko'rsatmalarini almashtirish orqali yanada samarali amalga oshirilishi mumkin


dynamic_cast:


dp = dynamic_cast (bp);


Operator dynamic_cast muvaffaqiyatli faqat holda amalga oshiriladi, chunki, agar ob'ekt, turiga olib operatsiya duchor, allaqachon berilgan turi ham ob'ekt, yoki turi, berilgan olingan, keyin bu ko'rsatma bajarish so'ng, dp pointer ham nol qiymatini o'z ichiga oladi, yoki ob'ekt turi uchun pointer Derived. Bundan tashqari, dynamic_cast operatori faqat ma'lum bir turdagi haydash operatsiyalari qonuniy bo'lsa, muvaffaqiyatli amalga oshirilganligi sababli, ba'zi hollarda uning mantiqi soddalashtirilishi mumkin. Quyidagi dastur typeid operatorini dynamic_cast operatori bilan qanday almashtirish mumkinligini ko'rsatadi. Bu erda bir xil operatsiyalar to'plami ikki marta amalga oshiriladi: birinchi typeid operatoridan va keyin dynamic_cast operatoridan foydalaning.


/ * Operator foydalanish dynamic_cast o'rniga operator typeid.


*/


#include

#include


using namespace std;


class Base {


public:

virtual void f() {}

};


class Derived : public Base {

public:

void derivedOnly() {

cout <\n";


}


};

int main()


{


Base *bp, b_ob;

Derived *dp, d_ob;


//--------------------------------


// Operator typeid foydalanish


//--------------------------------


bp = &b_ob;


if(typeid(*bp) == typeid(Derived)) {


dp = (Derived *) bp;


dp->derivedOnly();


}
else


cout < "



<\n";

bp = &d_ob;


if(typeid(*bp) == typeid(Derived)) {


dp = (Derived *) bp;


dp->derivedOnly();


}
else


cout < < "xato, haydovchi turi kerak" <


amalga oshirildi!\n";


//--------------------------------------


// Dynamic_cast operatoridan foydalanish


//--------------------------------------


bp = &b_ob;


dp = dynamic_cast (bp);


if(dp) dp->derivedOnly();


boshqa cout < < < "base turi ob'ektini olib kelish jarayoni" <"


derived turi bajarilmadi.\n"; bp = &d_ob;


dp = dynamic_cast (bp);


if(dp) dp->derivedOnly();


boshqa cout < < "xato, turi olib kelishi kerak" <\n";


return 0;


}


Ko'rib turganingizdek, dynamic_cast operatoridan foydalanish markerni asosiy sinfga lotin sinfiga indeksga aylantirish uchun zarur bo'lgan mantiqni osonlashtiradi. Ushbu dasturning natijalari shu tarzda ko'rinadi.

Derived turiga base turi ob'ektini olib operatsiya bajarilmadi.


Bu sinf Derived ob'ekt hisoblanadi. Base turi ob'ektini olib operatsiya


Derived turi bajarilmadi. Bu sinf Derived ob'ekt hisoblanadi.


Bundan tashqari. Dynamic_cast operatori shablon sinflariga nisbatan ham ishlatilishi mumkin.


Const_cast operatori


Const_cast operatori const va/yoki volatile modifikatorlarini bekor qiladi.


Const_cast operatori const va/ yoki volatile modifikatorlarini aniq bekor qilish uchun ishlatiladi. Yangi turdagi manba bilan mos kelishi kerak, uning xususiyatlari const yoki volatile tashqari. Ko'pincha const_cast operatori doimiylik belgisini (const atributi) olib tashlash uchun ishlatiladi. Uning umumiy formati quyidagi ko'rinishga ega.


const_cast (expr)


Bu erda "type" elementi yangi turdagi operatsiyani belgilaydi va expr elementi yangi turga olib keladigan ifodani bildiradi.


Const_cast operatoridan foydalanish quyidagi dasturda ko'rsatiladi.


// Const_cast operatoridan foydalanishni namoyish qilish.


#include


using namespace std;


void f (const int *p)


{


int *v;

// Const atributini bekor qilish.


v = const_cast (p);


* v = 100; // endi ob'ektni o'zgartirish mumkin


}


int main()

{


int x = 99;

cout < < "funktsiya qo'ng'iroq oldin X qiymati f ():" < x<;


f (&x);

cout < < "funktsiya f qo'ng'iroq keyin X qiymati ():" < x< ;

return 0;


}


Ushbu dasturning natijalari quyidagicha.

Funktsiya f qo'ng'iroq oldin x qiymati (): 99


Funktsiya f keyin x qiymati (): 100


Ko'rib turganingizdek, o'zgaruvchilar x funktsiyasi tomonidan o'zgartirilgan f (), parametr bo'lsa-da,, u tomonidan qabul, sifatida belgilangan const-pointer.



Download 62,5 Kb.

Do'stlaringiz bilan baham:
  1   2   3




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish