Factory konstruktorlari
Agar Siz o’z klassidan har doim ham obyekt olmaydigan konstruktor yaratmoqchi bo’lsangiz factory kalitso’zini konstruktoringiz oldidan qo’shib ketishingiz kerak bo’ladi. Masalan, factory konstruktor keshdan yoki o’zining subtype’idan obyekt qaytarishi mumkin. Factory konstruktorlari uchun yana bir holat — bu boshlang’ich ro’yhatida ko’rib bo’lmaydigan logic (kalitso’z) yordamida yakuniy o’zgaruvchini ishga tushirish.
Quyidagi misolda, Logger factory konstruktori keshdan obyekt qaytaradi va Logger.fromJson factory konstruktori JSON obyektidan o’zgaruvchi yaratadi.
class Logger {
final String name;
bool mute = false; // _cache - maxfiy o'zgaruvchi,
// o'zgaruvchidan oldinda turgan "_" uni maxfiy qiladi.
static final Map _cache =
{}; factory Logger(String name) {
return _cache.putIfAbsent(
name, () => Logger._internal(name));
} factory Logger.fromJson(Map json) {
return Logger(json['name'].toString());
} Logger._internal(this.name); void log(String msg) {
if (!mute) print(msg);
}
}
Eslatma: Factory konstruktorlaridathis ga kirishga huquq yo’q.
Boshqa konstruktorlarni qanday chaqirsangiz, factory konstruktorlarni ham shunday chaqirasiz:
var logger = Logger('UI');
logger.log('Button clicked');var logMap = {'name': 'UI'};
var loggerJson = Logger.fromJson(logMap);
Konstruktorlar va dyestruktorlar
Nomlaridan ko‘rinib turganidyek, konstruktor - bu myetod bo‘lib, u o‘z xotirasida ushbu sinf ob’yektini quradi, dyestruktor esa - bu ob’yektni olib tashlaydigan myetod. Konstruktorlar va dyestruktorlar boshqa ob’yektli myetodlardan quyidagi xususiyatlariga ko‘ra afrqlanadi:
O‘z sinfi nomi bilan bir xil bo‘lgan nomga ega.
Qaytariladigan qiymatga ega emas.
Garchi hosila sinf bazaviy sinflarning konstruktorlari va dyestruktorlarini chaqira olsa-da, konstruktor va dyestruktorlarning o‘zlari vorislik qilolmaydi.
Agar boshqacha e’lon qilinmagan bo‘lsa, kompilyator tomonidan avtomatik tarzda public sifatida gyenyeratsiya qilinadi.
Sinf ob’yektlarining yaratilishi va yo‘q qilinishini tyegishli tarzda kafolatlash uchun, kompiyaltor tomonidan chaqirib olinadi.
Agar ob’yekt dinamik xotiraning ajratilishi va yo‘q qilinishini talab qilsa, new va delete opyeratorlariga noaniq murojaatga ega bo‘lishi mumkin.
Quyida konstruktorlar va dyestruktorlar e’lonining umumlashma sintaksisini namoyish qiluvchi misol kyeltiramiz:
class className
{public:
//className ma’lmotlarining boshqa a’zolari; //yashirin className bo‘yicha konstruktor(
className(const className&);//Nusha ko‘chirish konstruktori
//Boshqa konstruktorlar
~className();//Dyestruktor
//Boshqa myetodlar};
Sinf soni chyeklanmagan konstruktorlarga ega bo‘lishi, shu jumladan, konstruktorlarga umuman ega bo‘lmasligi mumkin. Konstruktorlar virtual dyeb e’lon qilinishi mumkin emas. Hamma konstruktorlarni himoyalangan syektsiyaga joylashtirmang hamda, yashirin argumyentlar qiymatidan foydalanib, ularning sonini kamaytirishga intiling.
Ko‘p hollarda sinf ob’yektlarini initsializatsiya qilish (nomlash) ning bir nyechta usullariga ega bo‘lish yaxshi natija byeradi. Bunga bir nyechta konstruktor vositasida erishish mumkin. Masalan:
class date {
int vonth, day, year;
public:
// ...
date(int, int, int); //yilning oyi, kuni
date(char*); //satr ko‘rinishidagi sana
date(int); //bugungi kun, oy, yil
date(); //yashirin sana: bugungisi
};
Ortiqcha yuklangan funktsiyalar qanday qoidalarga amal qilsa, konstruktorlar ham paramyetrlar turlariga nisbatan xuddi shunday qoidalarga amal qiladilar. Agar konstruktorlar o‘z paramtyerlari turlari bo‘yicha ancha-muncha farq qilsa, kompilyator har gal foydalanganda to‘g‘ri paramyetrni tanlab olishi mumkin:
date today(4);
date july4(«1983 yil, 4 iyul»);
date guy(«5 Noy»)
date now; //yashirish initsiallashadi (nomlanadi.)
Konstruktorlarning uch turi mavjud.
Yashirin konstruktor paramyetrlarga ega emas. Agar sinf bitta ham konstruktorga ega bo‘lmasa, kompilyator avtomatik tarzda bitta yashirin konstruktor yaratadiki, u o‘z sinfiga mansub ob’yektni yaratishda xotirani shunchaki ajratib byeradi.
Date holatida har bir paramyetr uchun «yashirin qabul qilish: today» (bugun) sifatida talqin qilinadigan yashiringan qiymatni byerish mumkin.
class date {
int month, day, year;
public:
// ...
date(int d =0, int m =0, int y =0);
date(char*); // satr vositasida byerilgan sana
};
date::date(int d, int m, int y)
{
day = d ? d : today.day;
month = m ? m : today.month;
year = y ? y : today.year;
// yo‘l qo‘yiladigan sana ekanini tukshirish
// ...
}
Dalillarga ega konstruktor ob’yektning yaratilish paytida uni initsiallash (nomlash) ga, ya’ni turli funktsiyalarni chaqirib olishga, dinamik xotirani ajratish, o‘zgaruvchilarga dastlabki qiymatlarni byerish va h.k. ga imkon byeradi.
Nusha ko‘chirish konstruktori byerilgan sinf ob’yektlarini yaratish uchun ma’lumotlarni ushbu sinfning mavjud bo‘lgan boshqa ob’yektidan nusha ko‘chirish yo‘lidan borishga mo‘ljallangan. Bunday konstruktorlar ma’lumotlarning dinamik tuzilmalarini modyellashtiradigan ob’yektlar nushasini yaratishda ayniqsa maqsadga muvofiqdir. Biroq yashirin holda kompilyator yuzaki nushalash konstruktorlari (shallow copy constructors) dyeb ataluvchi faqat ma’lumotlar a’zolaridan nusha oladigan konstruktorlarni yaratadi. SHuning uchun, agar biron-bir ma’lumotlar a’zolari ko‘rsatkichlarga ega bo‘lsa, ma’lumotlarning o‘zidan nusha ko‘chirilmaydi. «CHuqur» nushalashni konstruktor kodiga joriy qilish uchun tyegishli yo‘riqnomalarni kiritish kyerak.
Misol:
class string
{
char *Str;
int size;
public:
string(string&); // nusxa ko‘chirish konstruktorlari
};
string::string(string& right) // dinamik o‘zgaruvchilar va rusurslar
{ // nusxalarini yaratadi
s = new char[right->size];
strcpy(Str,right->Str);
}
Mavzu: Fayllar bilan ishlashning yangi usullari (I/O texnologiyasi).
C++ da fayllar bilan ishlash
Ma`lumotlarni saqlab qo`yish uchun, tashqi xotiraning nomlangan qismiga fayl deyiladi. Bunday fayllar fizik fayllar deyiladi.
Mantiqiy fayllar. Fizik fayllar bilan ishlash uchun, programmalashtirish tillarida maxsus strukturalashgan, toifalangan fayllar kiritilgan. Bunday fayllar mantiqiy (logicheskiy) fayllar deyiladi. Mantiqiy fayllar, hech qanday fizik xotirani band qilmasdan ma`lumotlarning mantiqiy modelini o`zida saqlaydi.
Fizik va mantiqiy fayllar bir - biri bilan fopen funksiyasi orqali bog'lanadi.
Fayl bir nechta elementdan tashkil topgan bo`lganligi uchun, faqat fayl ko`rsatkichi ko`rsatayotgan elementga murojaat qilish mumkin. Fayldan o'qish yoki yozish mumkin bo'lgan o'rinni ko'rsatuvhi elementga fayl ko'rsatkichi deyiladi. Fayldan ma'lumot o'qiganda yoki yozganda fayl ko'rsatkichi avtomat ravishda o'qilgan yoki yozilgan bayt miqdoricha siljiydi. Fayl ko'rsatkichini magnitafon galovkasiga o'xshatish mumkin.
Binar fayl - har xil ob'ektlarni ifodalovchi baytlar ketma - ketligidir. Ob'ektlar faylda qanday ketma - ketlikda joylashganini programmaning o'zi aniqlashi lozim. Fayllar bilan ishlovchi funksiyalardan foydalanish uchun sarlavha faylini
programmaga qo'shish kerak bo'ladi.
Fayldan ma'lumotlarni o'qish yoki yozish uchun ochish fopen funksiyasi orqali amalga oshiriladi.
FILE * fopen ( const char * filename, const char * mode );
filename - o'zgaruvchisi char toifasidagi satr bo'lib, faylning to'liq nomini ko'rsatishi lozim
(filename = "D:\c++\misol.txt"). Agar faylning faqat nomi ko'rsatilgan bo'lsa, fayl joriy katalogdan qidiriladi (filename = "misol.txt").
mode - o'zgaruvchisi ham char toifasidagi satr bo'lib, faylni qaysi xolatda ochish lozimligini bildiradi. mode qiymati faylning ochilish xolati faylni yozish uchun ochish. falename o'zgaruvchisida ko'rsatilgan fayl hosil qilinadi va unga ma'lumot yozish mumkin"w" bo'ladi. Agar fayl oldindan bor bo'lsa (ya'ni oldin hosil qilingan bo'lsa), faylning ma'lumotlari o'chiriladi va yangi bo'sh fayl faqat yozish uchun ochiq holda bo'ladi. Fayl o'qish uchun ochiladi. Agar fayl oldindan mavjud bo'lmasa,"r" xatolik sodir bo'ladi. Ya'ni ochilishi lozim bo'lgan fayl oldindan hosil qilingan bo'lishi shart.
Faylga yangi ma'lumotlar qo'shish - kiritish uchun ochiladi."a"Yangi kiritilgan ma'lumotlar fayl oxiriga qo'shiladi. Agar fayl
oldindan mavjud bo'lmasa, yangi fayl hosil qilinadi. Yozish va o'qish uchun faylni ochish. Agar fayl oldindan bor bo'lsa (ya'ni oldin hosil qilingan bo'lsa), faylning ma'lumotlari "w+"o'chiriladi va yangi bo'sh fayl yozish va o'qish uchun ochiqholda bo'ladi. "r+"Oldindan mavjud bo'lgan faylni o'qish va yozish uchun ochish. Fayl ma'lumotlarni o'qish va yangi ma'lumot qo'shish uchun "a+" ochiladi. fseek, rewind faylni ochishda xatolik sodir bo'lsa, fopen funksiyasi NULL qiymat qaytaradi.
Ochilgan faylni yopish uchun fclose funksiyasi ishlatiladi.
int fclose ( FILE * stream );
Faylni yopishda xato sodir bo'lmasa, fclose funksiyasi nol qiymat qaytaradi. Xato sodir bo'lsa, EOF - fayl oxiri qaytariladi.
Faylga ma'lumot yozish va o'qish size_t fread ( void * ptr, size_t size, size_t n, FILE * stream ); fread funksiyasi, fayldan ptr ko'rsatkichi adresiga size xajmdagi ma'lumotdan n tani o'qishni amalga oshiradi. Agar o'qish muvoffaqiyatli amalga oshsa fread funksiyasi o'qilgan bloklar soni n ni qaytaradi. Aksholda nol qaytariladi size_t fwrite ( const void * ptr, size_t size, size_t n, FILE * stream ); fwrite funksiyasi, faylga ptr ko'rsatkichi adresidan boshlab size xajmdagi ma'lumotdan n tani yozishni amalga oshiradi.
Misol 1. fread va fwrite funksiyalarining qo'llanilishi
Do'stlaringiz bilan baham: |