logo

Dynamik_cast operatori

Загружено в:

12.08.2023

Скачано:

0

Размер:

55.892578125 KB
2  “Dynamik_cast operatori”
1.Operator Dynamic Cast
2.Diynamic Cast Operatori Haqida
3.Dynamik Cast Operatori Va Statik Cast
                                                                                                                                          3                            Operator dynamic_cas                                                
   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 <<””;
                                                                                                                                          4Turi 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 < < "t
urlari olib" <\n";
                                                                                                                                          5cout << 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 
                                                                                                                                          6bajarish 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);
                                                                                                                                          7if(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.                   
                                2. Dynamic_cast operatori haqida
 
Dynamic_cast operatori dastur bajarilishi davomida polimorf turdagi quyish amalini bajaradi. Yangi 
operatorlardan eng muhimi dynamic_cast tipidagi tip almashtirish (kasting, casting) operatoridir. Dasturni 
bajarish davomida taklif qilinayotgan amalning bajarilishini tekshiradi. Agar belgilangan amal 
chaqirilganda yaroqsiz bo‘lsa, hech qanday turdagi kasting amalga oshirilmaydi. Dynamic_cast operatorini 
qo‘llashning umumiy formati quyidagicha:
                                                                                                                                          8dynamic_cast (expr)
Bunda type elementi bu amalning maqsadi bo‘lgan yangi tipni, expr elementi esa bu yangi tipga 
almashadigan ifodani bildiradi. Tip turi ko‘rsatkich yoki mos yozuvlar bilan almashishi kerak va expr ifoda 
ko‘rsatkich yoki mos yozuvlar uchun tashlanishi kerak. Shu tarzda dynamic_cast operatoridan bir turdagi 
ko‘rsatgichni boshqa turdagi ko‘rsatgichga yoki bir turdagi murojaatni boshqa turdagi murojaatga 
aylantirish uchun foydalanish mumkin.
Bu operator asosan polimorf tiplar orasida dinamik tipni quyish amallari uchun ishlatiladi. masalan, agar 
polimorf sinflar B va D bo‘lsin. sinf D va sinf V olingach, dynamic_cast operatori yordamida, har doim 
ko‘rsatkichni Dga aylantirish mumkin. Chunki *in pointer* tayanch sinfga ko‘rsatkich har doim bazasidan 
olingan sinf ob yektini ko‘rsatish uchun foydalanish mumkin. Biroq, dynamic_cast operatori faqat ʻ
ko‘rsatkich aylantirishi mumkin. D ob yekt ko‘rsatkich uchun murojaat qilinganda, albatta, sinf D ob yekti 	
ʻ ʻ
bo‘ladi. Umuman olganda, dynamic_cast operatori faqat polimorf tipdagi kastingga ruxsat berilsa, 
muvaffaqiyatli bajariladi, ya ni yangi tipdagi ko‘rsatikch ushbu yangi tipdagi ob yektga yoki undan olingan	
ʻ ʻ
ob yektga havola qilishi mumkin. Aks holda, agar belgilangan tipdagi almashish amalini bajarib bo‘lmasa, 	
ʻ
bu amalda ko‘rsatgichlar ishtirok esa dinamic_cast operatorining natijasi null qiymatga aylanadi. Agar 
ushbu amalni bajarilishi muvaffaqitsiz bo‘lsa, uzilishlar ishtirok etgan bo‘lsa, bad_cast istisnosi avtomatik 
bajariladi.
Oddiy misolni ko‘rib chiqamiz. Base asos sinfi polimorf sinf bo‘lsin va myClass sinf esa Base sinfidan 
olingan deb faraz qilaylik.
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 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.	
ʻ ʻ
Base *bp;
Derived *dp;
// . . .
if(typeid(*bp) == typeid(Derived))
dp = (Derived *) bp;
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.
                                                                                                                                          9dynamic_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.
3. Berilgan float turidagi to’plamning 2 ta elementi yig’indisidan 2- to’plamni, ayirmasidan 3- to’plamni 
hosil qiluvchi va ularni ekranga chiqaruvchi dastur tuzing. Ikkala to’plamdan ham bir xil qiymatli elemetlar
o’chirilib Saralangan to’plam hosil qilinsin hamda uning qiymatlari ekranga chiqarilsin.
Ma`lumotlar tipini keltirish ( data casting ) Goxida bir turdagi o`zgaruvchining qiymatini boshqa tipdagi 
o`zgaruvchiga berish kerak boladi. Bu amal ma`lumot tipini keltirish ( data type casting) deyiladi. Ko`p 
hollarda bu amal avtomatik ravishda, kompilyator tarafidan. Masalan ushbu parchani ko`raylik:    char 
C=33;    int k;    k=c;    result = f+I;    C++ning kompilyatori ikki turdagi o`zgaruvchilari bilan ishlay 
olmaydi . shu sababli ifodadagi sig`im kichik bolgan o`zgaruvchilar ifodadagi qatnashgan eng    katta 
sig`imga o`tqaziladi. Bu ham avtomatik tarzda bajariladi. o`zgaruvchimiz qiymati vaqtinchalik float 
tipidagi o`zgaruvchiga beriladi. Bu vaqtinchalik o`zgaruvchi esa f ga qo`shiladi. Chiqqan jovob result ga 
beriladi. Bu kabi tip o`zgarishlarni avtomatik konversiya (implicit conversion ) deymiz. Lekin gohida 
to`g`ri kelmaydigan tiplarni birga qollashga to`g`ri keladi. Masalan float tipiga double tipni otqazish, char 
ga int va h.k. bu hollarda ochiq konversiya ( explicit conversion ) amalini bajarishimiz kerak. Buni 
bajarishning ikki usuli bor. Birinchisi C da qo`llaniladigan yol, ikkinchisi C++uslubi. C da tipni keltirish 
uchun o`zgaruvchi oldiga kerakli tipni () qavslar ichida yozamiz .    int k= 100    Char s;    S=(char)k; “ 
Yuqorida k ning qiymatini char tipidagi vaqtinchalik ozgaruvchiga berildi. Keyin s ga ushbu ozgaruvchi 
qiymatini berildi. Bu yerda etibor berilish kerak bolgan narsa shuki, 100 char ga ham tog`ri keladi. Agar k 
ning qiymati char oladigan qiymattan kattaroq kichikroq boladigan bolsa bu hatoga olib keladi. Shu sababli 
C dagi tip ketirish nisbatan havfli hisoblanadi. Lekin albatta bilib qolanilsa hato kata yordam beradi. C++ 
da ma`lumotlar tipini keltirish uchun maxsus operatorlar kiritildi.C uslubidagi keltirish hamma sharoitda 
qollanilar edi. C++ ning keltirish operatorlari esa faqat oziga ajratilgan funksiyalarni bajaradi. Undan 
tashqari ular C dagi keltirishlardan ko`ra kuchsizroqdir. Shu sababli hato ehtimoli kamaytiriladi. Yana bir 
afzallik tarafi shundaki yangi stildagi keltirish operatorlari tip tekshirishlarni bajarishadi agar notog`ri 
keltirish bajarilsa, bu sintaktik hatoga olib keladi.    Ular quyida berilgan:    static_cast    dynamic_cast    
const_cast    reinterpret_caste    static_cast ni ko`rib chiqaylik    int k=200;    char h;    h = static_cast(k); 
Static_cast dan keyin kerakli tip nomi <> qavslar ichida beriladi, va tipi o`zgarish kerak bolgan ozgaruvchi 
() qavslar ichida parameter sifatida beriladi. Static _cast kompilyatsiya davrida tip keltirilishidan 
qollaniladi. Dynamic_cast esa dastur ishlash davrida tip keltirishlari uchun qollaniladi. Consr_case esa 
o`zgaruvchilardan const (o`zgarmas) va volatile ( o`zgaruvchan uchuvchan ) sifatlarni olib tashlashda 
qollanniladi. Odatda const o`zgaruvchining qiymatini ozgartirib bolmaydi. Ushbu holda const_cast 
qo`llaniladi. Reinterprent_cast odatiy bolmagan keltirishlarni bajarishda qollaniladi.( masalan void* ni int 
ga). Reinterpret_cast o`zgaruvchining bitlarini boshqa manoda qo`llashga imkon beradi. Bu operator bilan 
keyinroq yanada yaqin tanishamiz. Matematik kutubhona funksiyalari. Standart kutubhonaning matematik 
funksiyalari kopgina amallarni bajarishga imkon beradi. Biz bu kutubxona misolida funksiyalar bilan 
ishlashni korib chiqamiz. Masalan bizning dasturimizda quyidagi satr bor bolsin:    Double= k;    Int m = 
123;    K= sin(m); Kompilyator ushbu satrni korganda, standart kutubhonadan sin funksiyasini chaqiradi. 
Kirish qiymati sifatida m ni berdik. Jovob yani funksiyadan qaytgan qiymat k ga berildi. Funksiya 
argumentlari ozgarmas sonlar ( konstanta) o`zgaruvchilar, ifodalar va boshqa mos keluvchi qiymat 
qaytaradigan funksiyalar bolishi mumkin. Masalan:    Int g = 49. K = 100;    Cout<”<70; Matematik 
funksiyalar aksariyat hollarda double tipidagi qiymat qaytarishadi. Kiruvchi argumentning tipi sifatida esa 
double ga keltirilishi mumkin bo`lgan tip beriladi. Bu funksiyalarni keltirish uchunmath.h ( yangi 
korinishda cmathg) e`lon faylini include bilan asosiy dasturtanasiga kiritish kerak . quyidagi matematik 
funksiyalar kutubhonalarining bazi bir a`zolarini beraylik x va y o`zgaruvchilari double tipiga ega. 
Funksiyani aniqlanishi Misol    Ceil (x) x ni x dan katta yoki unga teng bilan ceil (12.6)= 13.0    Eng kichik 
butun songacha yaxlitlaydi ceil(-2.4)=-2.0    Cos (x) x ning trigonometrik kosinusi ( x radianda) cos 
(0.0)=1.0    Exp (x) e ning x chi darajasi ( eksponetsial f-ya ) exp (1.0) = 2.71828    Exp(2.0) = 7.38 906    
Fabs(x) x ning absolyut qiymati x>0=>abs(x)=x    X=0=>abs(x)=0.0    Xabs (x)=-x    Floor(x) x ni x dan 
kichik bolgan eng kata floor (4.8)=4.0    Butun songacha yaxlidlaydi floor (-15.9)= -16.0    Fmod(x,y)x/y 
ning qoldig1ini kasr son tipida beradi fmod (7.3,1.7)=0.5    Log(x) x ning natural lagarifmi (e asosiga kora) 
                                                                                                                                          10log(2.718282) = 1.0    Log10(x) x ning 10 asosiga ko`ra lagarifmi log10(1000.0)= 3.0    Pow (x,y) x ning y 
chi darajasini beradi pow(3,4) = 81.0    Pow (16,0.25) =2    Sin(x) x ning trigonometrik sinusi ( x radianda) 
sin (0.0) = 0.0    Sqrt (x) x ning trigonometric tangensi (x radianda) tan (0.0) = 0
FUNKSIYALARNING TUZILISHI  
Funksiyalar dasturchi ishini juda yengillashtiradi. Funksiyalar yordamida programma modullashadi, 
qismlarga bo'limadi. Bu esa keyinchalik dasturni rivojlantirishni osonlashtiradi. Dastur yozilish davrida 
hatolarni topishni yengillashtiradi. Bir misolda funksiyaning asosiy qismlarini ko'rib chiqaylik.
   
int foo(int k, int t) {
int result; 
result = k * t; 
return (result); 
} 
   
Yuqoridagi foo funksiyamizning ismi, () qavslar ichidagi parametrlar – int tipidagi k va t lar kirish 
argument-laridir, ular faqat ushbu funksiya ichida ko'rinadi va qo'llaniladi. Bunday o'zgaruvchilar 
lokal(local-mahalliy)
deyiladi. result foo() ning ichida e'lon qilinganligi uchun u ham lokaldir. Demak biz funksiya ichida 
o'zgaruvchilarni va klaslarni (class) e'lon qilishimiz mumkin ekan. Lekin funksiya ichida boshqa funksiyani
e'lon qilib bo'lmaydi. foo() funksiyamiz qiymat ham qaytaradi. Qaytish qiymatining tipi foo() ning e'lonida 
eng boshida kelgan - int tipiga ega. Biz funksiyadan 
qaytarmoqchi bo'lgan qiymatning tipi ham funksiya e'lon qilgan qaytish qiymati tipiga mos kelishi kerak - 
ayni o'sha tipda bo'lishi yoki o'sha tipga keltirilishi mumkin bo'lgan tipga ega bo'lishi shart. Funksiyadan 
qiymatni
return ifodasi bilan qaytaramiz. Agar funksiya hech narsa qaytarmasa e'londa void tipini yozamiz. Yani: 
   
void funk(){
int g = 10; 
cout << g;
return; 
} 
Bu funksiya void (bo'sh, hech narsasiz) tipidagi qiymatni qaytaradi. Boshqacha qilib aytganda qaytargan 
qiymati bo'sh to'plamdir. Lekin funksiya hech narsa qaytarmaydi deya olmaymiz. Chunki hech narsa 
qaytarmaydigan mahsus funksiyalar ham bor. Ularning qaytish qiymati belgilana-digan joyga hech narsa 
yozilmaydi. Biz unday funksiyalarni keyinroq qo'rib chiqamiz. Bu yerda bir nuqta shuki, agar funksiya 
                                                                                                                                          11mahsus bo'lmasa, lekin oldida qaytish qiymati tipi ko'rsatilmagan bo'lsa, qaytish qiymati int tipiga ega deb 
qabul qilinadi.
Void  qaytish tipli funksiyalardan chiqish uchun return; deb yozsak yetarlidir.Yoki return ni qoldirib ketsak
ham   bo'ladi.   Funksiyaning   qismlari   bajaradan   vazifasiga   ko'ra   turlicha   nomlanadi.   Yuqorida   korib
chiqqanimiz funksiya aniqlanishi (function definition) deyiladi, chunki biz bunda funksiyaning bajaradigan
amallarini funksiya nomidan keyin,{} qavslar ichida aniqlab yozib chiqyapmiz. Funksiya aniqlanishida {}
qavslardan   oldin   nuqta-vergul   (;)   qo'yish   hatodir.   Bundan   tashqari   funksiya   e'loni,   prototipi   yoki
deklaratsiyasi   (function   prototype)   tushunchasi   qo'llaniladi.   Bunda   funksiyaning   nomidan   keyin   hamon
nuqta-vergul   qo'yiladi,   funksiya   tanasi   esa   berilmaydi.   C++   da   funksiya   qo'llanilishidan   oldin   uning
aniqlanishi   yoki   hech   bo'lmaganda   e'loni   kompilyatorga   uchragan   bo'lishi   kerak.   Agar   funksiya   e'loni
boshqa   funksiyalar   aniqlanishidan   tashqarida   berilgan   bo'lsa,   uning   kuchi   ushbu   fayl   ohirigacha   boradi.
Biror bir funksiya ichida berilgan bo'lsa kuchi faqat o'cha funksiya ichida tarqaladi. E'lon fayllarda aynan
shu funksiya e'lonlari berilgan bo'ladi. Funksiya e'loni va funksiya aniqlanishi bir-biriga mos tushishi kerak.
Funksiya e'loniga misol:    
double square(char, bool);
float average(int a, int b, int c);    
Funksiya e'lonlarda kirish parametrlarining faqat tipi yozish kifoya, huddi square() funksiyasidek. Yoki 
kiruvchi parametrlarning nomi ham berilishi mumkin, bu nomlar kompilyator tarafidan etiborga olinmaydi, 
biroq dasturning o'qilishini ancha osonlashtiradi. Bulardan tashqari C++ da funksiya imzosi (function 
signature) tushunchasi bor. Funksiya imzosiga funksiya nomi, kiruvchi parametrlar tipi, soni, ketma-ketligi 
kiradi. Funksiyadan qaytuvchi qiymat tipi imzoga kirmaydi.  
int foo(); //No1 
int foo(char, int); //No2
double foo(); //No3 - No1 funksiya bilan imzolari ayni. 
void foo(int, char); //No4 - No2 bilan imzolari farqli. 
char foo(char, int); //No5 - No2 bilan imzolari ayni. 
int foo(void); //No6 - No1 va No3 bilan imzolari ayni, 
// No1 bilan e'lonlari ham ayni. 
   
Yuqoridagi misolda kirish parametrlari bo'lmasa biz () qavsning ichiga void deb yozishimiz mumkin (No6 
ga qarang). Yoki () qavslarning quruq o'zini yozaversak ham bo'ladi (No1 ga qarang). Yana bir tushuncha - 
funksiya chaqirig'idir. Dasturda funksiyani chaqirib,qo'llashimiz uchun uning chaqiriq ko'rinishini 
ishlatamiz. () qavslari funksiya chaqirig'ida qo'llaniladi. Agar funksiyaning kirish argumentlari bo'lmasa, () 
qavslar bo'sh holda qo'llaniladi. Aslida () qavslar C++ da operatorlardir.    Funksiya kirish parametrlarini har 
birini ayri-ayri yozish kerak, masalan yuqoridagi  
float average(int a, int b, int c); 
  funksiyasini  
float average(int a,b,c); // Hato!    
deb yozishimiz hatodir. 
                                                                                                                                          12   
Hali etib o'tganimizdek, funksiya kirish parametrlari ushbu funksiyaning lokal o'zgaruvchilaridir. Bu 
o'zgaruvchilarni funksiya tanasida boshqattan e'lon qilish sintaksis hatoga olib keladi. Bir dastur yozaylik.
   
//Funksiya bilan ishlash
# include 
   
int foo(int a, int b); //Funksiya prototipi, 
//argumentlar ismi shart emas. 
   
int main()
{ 
for (int k = 1; k 
for (int l = 5; l>0; l--){ 
cout << foo(k,l) << " "; //Funksiya chaqirig'i. 
}//end for (l...) 
cout << endl; 
}//end for (k...) 
return (0);
} //end main() 
   
//foo() funksiyasining aniqlanishi
int foo(int c, int d) 
{ //Funksiya tanasi 
return(c * d); 
} 
                                                                                                                                          13Ekranda: 
   
5 4 3 2 1
10 8 6 4 2 
Bizda ikki sikl ichida foo() funksiyamiz chaqirilmoqda. Funksiyaga k va l o'zgaruvchilarining nushalari 
uzatil-moqda. Nushalarning qiymati mos ravishda funksiyaning aniqlanishida berilgan c va d 
o'zgaruvchilarga berilmoqda. k va l ning nushalari deganimizda adashmadik, chunki ushbu 
o'zgaruvchilarining qiymatlari funksiya chaqirig'idan hech qanday ta'sir ko'rmaydi. C++ dagi 
funksiyalarning bir noqulay tarafi shundaki, funksiyadan faqat bitta qiymat qaytadi. Undan tashqari 
yuqorida ko'rganimizdek, funksiyaga berilgan o'zgaruvchilarning faqat nushalari bilan ish ko'rilarkan. 
Ularning qiymatini normal sharoitda funksiya ichida o'zgartirish mumkin emas. Lekin bu muammolar 
ko'rsatkichlar yordamida osonlikcha hal etiladi. Funksiya chaqiriqlarida avtomatik ma'lumot tipining 
konversiyasi bajariladi. Bu amal kompilyator tomonidan bajarilganligi sababli funksiyalarni chaqirganda 
ehtiyot bo'lish kerak. Javob hato ham bo'lishi mumkin. Shu sababli kirish parametrlar tipi sifatida katta 
hajmli tiplarni qo'llash maqsadga muofiq bo'ladi. Masalan double tipi har qanday sonli tipdagi qiymatni o'z 
ichiga olishi mumkin. Lekin bunday qiladigan bo'lsak, biz tezlikdan yutqazishimiz turgan gap. Avtomatik 
konversiyaga misol keltiraylik. 
   
int division(int m, int k){
return (m / k); 
}    
dasturda chaqirsak:...
float f = 14.7; 
double d = 3.6;
int j = division(f,d); //f 14 bo'lib kiradi, d 3 bo'lib kiradi 
// 14/3 - butun sonli bo'lish esa 4 javobini beradi 
cout << j; 
... 
  Ekranda: 
  4 
Demak kompilyator f va d o'zgaruvchilarining kasr qismlarini tashlab yuborar ekan.  Qiymatlarni pastroq 
sig'imli tiplarga o'zgartirish hatoga olib keladi. 
                                                                                                                                          14                                                                                                                                          15                                                                                                                                          16                                                                                                                                          17                                                                                                                                          18                                                                                                                                          19                                                                                                                                          20

2 “Dynamik_cast operatori” 1.Operator Dynamic Cast 2.Diynamic Cast Operatori Haqida 3.Dynamik Cast Operatori Va Statik Cast

3 Operator dynamic_cas 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 <<””;

4Turi 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 < < "t urlari olib" <\n";

5cout << 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

6bajarish 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);