C++ tur o'zgartirish operatorlari
Nomlangan translatsiyalardan foydalanish boshqa usullarga nisbatan C++ da type conversion ning xavfsizroq va ishonchli usuli hisoblanadi. C++ da to'rtta asosiy nomli tip-casting ifodalari mavjud:
static_castdynamic_castconst_castreinterpret_caststatic_cast dan float dan int ga aylantirish kabi standart turdagi konvertatsiyalar uchun foydalanamiz.
Keling, bir misolni ko'rib chiqaylik.
#include <iostream>
using namespace std;
int main() {
float my_float = 3.14;
// floatni int ga aylantiring
int my_int = static_cast<int>(my_float);
cout << "Float: " << my_float << " -> Int: " << my_int << endl;
return 0;
}
Chiqish
Float: 3.14 -> Int: 3
static_cast<int>(my_float) ifodasi my_float-da saqlangan float qiymatini butun songa aylantiradi va uni my_int-da saqlaydi.
Suzuvchi nuqta qiymatlari o'nlik komponentlarga ega bo'lishi va butun sonlar bo'lmasligi sababli, bu konvertatsiya o'nlik qismini olib tashlaydi va 3,14 ni 3 ga aylantiradi.
Biz asosan polymorphic tipidagi konvertatsiyalar uchun dynamic_cast dan foydalanamiz, ayniqsa inheritance ierarxiyasi bilan ishlashda. U odatda pointer tayanch sinfi olingan sinf ko‘rsatkichiga aylantirilishi kerak bo‘lgan stsenariylarda qo‘llaniladi.
Keling, bir misolni ko'rib chiqaylik.
#include <iostream>
using namespace std;
class Base {
public:
//
virtual void print() {
cout << "Base class" << endl;
}
};
class Derived : public Base {
public:
// tayanch sinfni bekor qiluvchi olingan sinfni chop etish funksiyasi
void print() override {
cout << "Derived class" << endl;
}
};
int main() {
// asosiy sinf ko'rsatkichini yarating
// Derived ob'ektga ishora qilish
Base *base_ptr = new Derived();
// uzatish uchun dynamic_cast dan foydalaning
// Olingan ko'rsatkichga asosiy ko'rsatkich
Derived *derived_ptr = dynamic_cast<Derived*>(base_ptr);
// olingan ko'rsatkich orqali chop etish funksiyasini chaqiring
if (derived_ptr) {
derived_ptr->print();
}
// dinamik ravishda ajratilgan ob'ektni o'chirish
delete base_ptr;
return 0;
}
Chiqish
Derived class
Bu misolda,
Base tayanch sinfini va Derived Base dan meros qilib olingan Derived sinfini aniqladik.main() da biz Derived obyektiga ishora qiluvchi Base* tipidagi base_ptr ko‘rsatkichini yaratdik.dynamic_cast -dan base_ptr -ni Derived* ko'rsatkichiga uzatish va uni derived_ptr -ga belgilash uchun foydalandik.print() funksiyasini derived_ptr orqali chaqirdik, ya'ni dinamik translatsiyadan so'ng Base sinf ko'rsatkichi orqali Derived sinf funksiyasiga kirishimiz mumkin.[!NOTE] Agar asosiy sinf ko'rsatkichi olingan sinf ob'ektiga ishora qilmasa,
dynamic_castnullptrni qaytaradi.
variable dan const kvalifikatsiyasini olib tashlash uchun const_cast dan foydalanamiz.
const_cast -dan foydalanishimiz mumkin bo'lgan umumiy stsenariylardan biri functions -ga ega bo'lgan uchinchi tomon kutubxonalari bilan ishlash bo'lib, ular doimiy bo'lmagan ko'rsatkichlarni argument sifatida qabul qiladi, ammo biz const ma'lumotlarini o'tkazishimiz kerak.
Keling, bir misolni ko'rib chiqaylik.
#include <iostream>
using namespace std;
// const bo'lmagan ko'rsatkichni oladigan funksiya
void modify_data(int* data) {
// ma'lumotlarni o'zgartirish
*data *= 2;
}
int main() {
int x = 10;
// x o'zgaruvchisi uchun const ko'rsatkichi
const int* ptr = &x;
// const_cast dan foydalaning
// const kvalifikatsiyasini olib tashlang va o'zgartirishga ruxsat bering
int* mutable_ptr = const_cast<int*>(ptr);
// funksiyani chaqiring
modify_data(mutable_ptr);
//
cout << "Modified value: " << x << endl;
return 0;
}
Chiqish
Modified value: 20
Ushbu misolda biz const_cast ifodasidan const kvalifikatorini argument sifatida konst bo'lmagan ko'rsatgichni qabul qiluvchi funksiya orqali o'tkazish uchun ko'rsatgichdan olib tashladik.
Bu yerga,
-modify_data(int* data) : argument sifatida const bo'lmagan ko'rsatgichni oladigan funksiya
-ptr: bu modify_data ga o'tishimiz kerak bo'lgan konst ko'rsatkichi
const_cast<int*>(ptr): casts ptr as a non-const pointer and assigns it to mutable_ptrreinterpret_cast bir ko'rsatkich turini boshqa ko'rsatkich turiga yoki bitta mos yozuvlar turini boshqa mos yozuvlar turiga aylantirish uchun ishlatiladi.
static_cast dan farqli o'laroq, reinterpret_cast aslida ma'lumotlar turlarini o'zgartirmaydi, lekin kompilyatsiya vaqtida bir ko'rsatkich turini boshqasi sifatida qayta talqin qiladi.
Keling, bir misolni ko'rib chiqaylik.
#include <iostream>
using namespace std;
int main() {
// butun sonli o'zgaruvchini yarating
int x = 67;
// butun songa ko'rsatkich
int* ptr_to_int = &x;
// ko'rsatgichni butun songa qayta talqin qilish
// charga ko'rsatkich sifatida
char* ptr_to_char = reinterpret_cast<char*>(ptr_to_int);
// qo'sh ko'rsatgichga murojaat qiling
// dastlab butun sonni xuddi dublni o'z ichiga olgandek ushlab turadi
cout << "Dereferencing ptr_to_char: " << *ptr_to_char << endl;
return 0;
}
Chiqish
Dereferencing ptr_to_char: C
Bu yerda biz reinterpret_cast dan dastlab butun songa ishora qilgan ptr_to_int ko‘rsatkichini belgiga ko‘rsatgich sifatida qayta talqin qilish uchun foydalandik.
Bu shuni anglatadiki, ptr_to_int tomonidan ko'rsatilgan xotira joyi hali ham butun son qiymatiga ega. Ammo u xarakter sifatida ko'rib chiqiladi.
[!NOTE]
reinterpret_castallows for almost any pointer or integer type conversion without any type safety checks. This can result in undefined behavior. So,reinterpret_castshould be used with caution.