Base *bp, b_ob; myClass - Tiplarni dinamik tarzda aniqlash. Reja: Tiplarni dinamik tarzda aniqlash

Base *bp, b_ob; myClass *dp, d_ob;
bp = &d_ob; // myClass sinf obʻyektga Base sinf uchun ko‘rsatkich.
dp = dynamic_cast< myClass *> (bp); // myClass sinf ko‘rsatgichga almashtirish if(dp) cout << " Tipni almashtirish muvaffaqiyatli bo‘ldi!";
Bu yerda bp ko‘rsatkichini (asos sinf) dp ko‘rsatkichiga (myClass sinf) almashtirish muvaffaqiyatli bo‘ladi, chunki bp aslida sinf obʻyektiga ishora qiladi.
myClass shuning uchun ushbu misolni bajarishda tipni almashtirish muvaffaqiyatli chiqdi. bp aslida sinf bazasini obʻyektga ishora qilgandi. Quyidagi misolda tipni almashtirishda myClass sinf obʻyekt bo‘lsa, ko‘rsatgichga tayanch sinfga obʻyektni tashlash uchun muvaffaqiyatsiz va noto‘g‘ri olingan hisoblanadi.
Base *bp, b_ob; myClass *dp, d_ob;
bp = &b_ob; // Base sinfga ko‘rsatkich sifatida Base sinf obʻyekt berilgan. dp = dynamic_cast< myClass *> (bp); // xatolik
if(!dp) cout << " Tipni almashtirish muvaffaqiyatsiz ";
|
Ushbu dastur fragmentida tipni almashtirish amali muvaffaqiyatsiz bo‘ldi va tipni almashtirish uchun muvaffaqiyatsiz bo‘lganligini ekranga chiqaradi.
dynamic_cast operatoridan foydalanishda quyidagi 1.7-dasturda tipni almashtirish holatlari aniqlaymiz.
1.7-dastur. dynamic_cast operatoridan foydalanish.
#include "stdafx.h"
#include
#include
using namespace std;
class Base {
public:
virtual void f() { cout << " Base sinfi orqali.\n"; }
// . . .
};
class myClass : public Base { public:
void f() { cout << "myClass sinfi orqali.\n"; }
};
int main(){
Base *bp, b_ob; myClass *dp, d_ob;
dp = dynamic_cast (&d_ob);
if(dp) {
cout << " tipni almashtirish" <<" (myClass* => myClass *) bajarildi. "; dp->f();
} else cout <<"Xatolik\n"; cout << endl;
bp = dynamic_cast (&d_ob);
if(bp) {
cout << " tipni almashtirish " <<"(myClass* => Base *) bajarildi. "; bp->f();
} else cout << "Xatolik\n"; cout << endl;
bp = dynamic_cast (&b_ob); if(bp) {
cout << " tipni almashtirish " <<"(Base* => Base *) bajarildi. "; bp->f();
} else cout << "Xatolik\n"; cout << endl;
dp = dynamic_cast (&b_ob); if(dp) cout <<"Xatolik\n";
else
cout <<" tipni almashtirish "<<"(Base*=> myClass*) bajarilmadi.\n"; cout << endl;
bp = &d_ob; // bp myClass ob'eyktiga koʻrsatkich dp = dynamic_cast (bp);
if(dp) {
cout << " bp ni myClass tipiga almashtirish bajarildi. ";
dp->f();
} else cout << "Xatolik\n"; cout << endl;
bp = &b_ob; // br Base ob'eyktiga koʻrsatkich dp = dynamic_cast (bp);
if(dp) cout << "Xatolik";
else cout <<" bp myClass tipiga almashtirish bajarilmadi.\n"; cout << endl;
dp = &d_ob; // dp myClass ob'eyktiga koʻrsatkich bp = dynamic_cast (dp);
if(bp) {
cout <<" dp ni myClass tipiga almashtirish bajarildi. "; bp->f();
}
else cout <<"Xatolik\n"; system("pause");
return 0; }
1.7 – dastur natijasi. Output
|
tipni almashtirish (myClass* => myClass *) bajarildi. myClass sinfi orqali. tipni almashtirish (myClass* => Base *) bajarildi. myClass sinfi orqali. tipni almashtirish (Base* => Base *) bajarildi. Base sinfi orqali.
tipni almashtirish (Base*=> myClass*) bajarilmadi.
bp ni myClass tipiga almashtirish bajarildi. myClass sinfi orqali. bp myClass tipiga almashtirish bajarilmadi.
dp ni myClass tipiga almashtirish bajarildi. myClass sinfi orqali.
|
Dynamic_cast operatori baʻzan typeid operatori o‘rniga ishlatilishi mumkin. Masalan, Base sinf polimorf va myClass sinf uchun asos sinf, deb faraz qilaylik. Quyidagi dastur fragmentini bajarishda, obʻyekt aslida myClass sinf obʻyekti bo‘lsada dp ko‘rsatkich bp ko‘rsatkich tomonidan obʻyekt manzili beriladi.
Bu holda, odatiy tipni almashtirish ishlatildi. Bu juda xavfsiz, chunki if operatori typeid operatori yordamida typeid amalining haqiqiyligini bajarilishidan oldin tekshiradi. Typeid operatori va if operatori bilan almashtirish orqali yanada samaraliroq qilish mumkin.
dynamic_cast:
dp = dynamic_cast (bp);
|
Dynamic_cast operatori faqat obʻyektning belgilangan tipi yoki belgilangan tipi almashtirilgan tipi bilan bir obʻyekt bo‘lsa muvaffaqiyatli natija beradi, bu almashtirish tugagandan so‘ng, dp ko‘rsatkich olingan obʻyektga null qiymatini yoki ko‘rsatkichni ham o‘z ichiga oladi. Belgilangan tipni tashlash amali to‘g‘ri bajarilgan bo‘lsa dynamic_cast operatori faqat muvaffaqiyatli bajariladi, uning almashtirish mantig‘ini muayyan vaziyatlarda soddalashtirilgan mumkin. Quyidagi 1.8-dastur typeid operatorini dynamic_cast operatori bilan almashtirish mumkinligini ko‘rsatilgan. Bu yerda bir xil amallar to‘plami ikki marta bajariladi, masalan, avval typeid operatori, so‘ngra dynamic_cast operatori yordamida.
|