• Standart bo‘yicha taqsimlovchilar.
  • Tiplarni dinamik tarzda aniqlash. Reja: Tiplarni dinamik tarzda aniqlash




    Download 0,81 Mb.
    bet53/143
    Sana20.07.2024
    Hajmi0,81 Mb.
    #268096
    1   ...   49   50   51   52   53   54   55   56   ...   143
    Bog'liq
    Tiplarni dinamik tarzda-fayllar.org

    Konteyner va uni qo‘llanilishi. Xotirada ko‘p hollarda merosxo‘r obʻyektlarini saqlovchi sinflar vujudga keladi. Ularning xotiradan o‘chirilishi bazaviy sinf bilan bog‘liqdir. Masalan, sinf bo‘lsin va tugun ichidagi matndan olingan mo‘rosxo‘rlari Node va Attribute hamda (char*) qatorlardan to‘ldirilgan. Yoki papkani qayta o‘qish va yana o‘zgartirishda, bir marta yuklanadi fayl menejeri fayllar va kataloglar ro‘yxati.
    Yuqorida ko‘rsatilgandek, new operatoriga nisbattan delete operatori foydalanish qiyinroq va muammoliroq bo‘ladi. Bazaviy sinf obʻyekti bilan bog‘liq katta blokda merosxo‘r sinf obʻyektlari uchun xotira ajratish kerak. Bazaviy sinf obʻyektini yo‘q qilish paytida, destruktor odatdagidek, merosxo‘r sinf uchun chaqiriladi, lekin xotirani qaytarishingiz shart emas — bu katta blokda ozod qilinadi.
    PointerBumpAllocator sinf yaratamiz. Bu sinf katta blokdan turli o‘lchamdagi qismlarni kesib tashlash va eskisi tugagach, yangi katta blokni tanlashga imkon beradi.
    PointerBumpAllocator sinfining dastur fragmenti.

    template class PointerBumpAllocator


    {public: PointerBumpAllocator() : free(0) { }
    void* AllocBlock(size_t block) {

    // todo: lock(this)


    block = align(block, Alignment); if (block > free) {
    free = align(block, PageSize); head = GetPage(free);
    } void* tmp = head;

    head = (char*)head + block; free -= block;


    return tmp;
    }
    ~PointerBumpAllocator() {
    for (vector::iterator i = pages.begin(); i != pages.end(); ++i)
    {VirtualFree(*i, 0, MEM_RELEASE);}
    }
    private: void* GetPage(size_t size) {
    void* page = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE,
    PAGE_READWRITE);
    pages.push_back(page); return page;}
    vector pages; void* head;
    size_t free;};
    typedef PointerBumpAllocator<> DefaultAllocator;

    Nihoyat, new va delete operatorlari bilan childObject ni tuzamiz va berilgan allocator bilan murojaat qilamiz:

    template struct ChildObject


    {static void* operator new(size_t s, A& allocator) { return allocator.AllocBlock(s);}
    static void* operator new(size_t s, A* allocator) { return allocator->AllocBlock(s);}
    static void operator delete(void*, size_t) { }

    static void operator delete(void*, A*) { } static void operator delete(void*, A&) { }


    private:
    static void* operator new(size_t s);
    };


    Child sinfiga o‘zgaruvchilarni qo‘shish uchun barcha eʻlonlarni new operatori orqali amalga oshirish kerak bo‘ladi. New operatori quyidagicha bo‘ladi.

    new (… parametrlar… ) ChildObject (…konstruktor parametrlari… )




    Qulaylik uchun A& va A* uchun new operatorlarni qo‘llaymiz.

    node = new(allocator) XmlNode(nodename);




    Agar allokator ajratuvchi sifatida qo‘shilsa, ikkinchisidan foydalanish qulayroq:

    node = new(this) XmlNode(nodename);




    Bundan tushinarli bo‘ladiki, ortiqcha belgilardan qochishda amallarni bo‘lish uchun ko‘rsatkich va havolalar konvertatsiya bo‘ladi.
    Obʻyekt yaratishda qaysi New operatoridan foydalanganligiga qaramasdan, delete operatori yordamida o‘chirish amalga oshirilmaydi, kompilyatorning o‘zi standart delete operatoridan foydalanadi. Quyidagicha sintaktik asosida:

    delete node;




    Agar ChildObject sinfi obʻyekti yoki uning merosxo‘ri obʻyektidan foydalanayotgan bo‘lsangiz, new istisno vaqtida operatoriga mos delete orperatori chaqiriladi. Shuning uchung bu obʻyektdan foydalanganda birinchi size_t parametrni void*ga o‘zgartirish lozim.
    New operatorini private bo‘limiga joylashtirish, uni allokatorsiz ishlashaga ruxsat bermaydi.

        Standart bo‘yicha taqsimlovchilar.



      1. Tuzilmali o‘zgaruvchisi uchun dinamik xotira ajratish. Tuzilmali o‘zgaruvchisi uchun xotira ajratish va bo‘shatish. Quyidagi tavsifga ega bo‘lgan data tuzilmasi berilgan bo‘lsin:

        struct Date


        {int day; int month; int year;
        };





    struct Date tipidagi o‘zgaruvchi uchun xotiradan joy ajratish va foydalanish uchun quyidagicha dastur fragmentini yozish kerak:
    5.10-dastur. xotiradan joy ajratish va foydalanish.

    #include "stdafx.h" #include using namespace std;


    // tuzilma, kun, oy, yil;
    struct Date
    {int day; int month; int year;};
    int main(){ // new operatori bilan xotiradan joy ajratish
    struct Date * pd; // struct Date ga koʻrsatkich
    try{ pd = new struct Date; // xotiraga joy ajratish
    } catch (bad_alloc ba) {cout << "Xorita ajratilmadi" << endl;
    return -1;}
    // Agar xotira ajratilgan boʻlsa, unga 16.14.2020 qimat qilib beramiz.
    pd->day = 16; pd->month = 04; pd->year = 2020;
    cout << pd->day << ":" << pd->month << ":" << pd->year << endl;
    // pd oʻzgaruvchisini xotiradan boʻshatish

    delete pd;system("pause"); return 0;}


    1   ...   49   50   51   52   53   54   55   56   ...   143




    Download 0,81 Mb.

    Bosh sahifa
    Aloqalar

        Bosh sahifa



    Tiplarni dinamik tarzda aniqlash. Reja: Tiplarni dinamik tarzda aniqlash

    Download 0,81 Mb.