Sobes.tech
Middle

Дар иҷрои амалиёти realloc, чӣ мешавад бо унсурҳои std::vector?

sobes.tech AI

Ҷавоб аз AI

std::vector истифода намекунад realloc. Вақте ки андозаи контейнер тағйир меёбад, ки талаб мекунад тақсимоти навгардиҳӣ, амалҳои зерин рӯй медиҳанд:

  1. Як минтақаи нави хотира бо андозаи кофӣ ҷудо карда мешавад.
  2. Элементҳо аз минтақаи кӯҳна ба минтақаи нав интиқол дода мешаванд.
    • Барои намудҳое, ки семантикаи интиқолро дастгирӣ мекунанд (T бо иҷрои дурустии конструктори интиқол ва/ё оператори таъинкунии интиқол), истифода мешавад интиқол. Ин самараноктар аст, зеро захираҳои кӯҳна (масалан, хотира, ки дар дохили объектҳо ҷудо шудааст) ба объектҳои нав интиқол дода мешаванд ва объектҳои кӯҳна дар ҳолати эътиборнок, аммо номаълуми мемонанд ё бо деструкторҳо тоза карда мешаванд.
    • Барои намудҳое, ки семантикаи интиқолро дастгирӣ намекунанд ё агар компилятор натавонад интиқолро татбиқ кунад, истифода мешавад нусхабардорӣ.
    • Агар элементҳо тривиалӣ нусхабардорӣшаванда бошанд (T навъи POD ё дорои амалҳои тривиалии нусхабардорӣ ва интиқол), метавон истифода бурд memcpy ё функсияҳои пастсифати дигар барои нусхабардории зудтари маълумот.
  3. Деструкторҳо барои элементҳо дар минтақаи кӯҳна даъват мешаванд.
  4. Минтақаи кӯҳнаи хотира озод карда мешавад.

Муҳим аст, ки ишораҳо ва истинодҳо ба элементҳо дар минтақаи кӯҳна пас аз тақсимоти нав нодуруст мешаванд.

#include <vector>
#include <iostream>
#include <string>

struct MyItem {
    std::string name;
    // Конструктор
    MyItem(const std::string& n) : name(n) {
        std::cout << "Constructing " << name << std::endl;
    }
    // Конструктор нусхабардорӣ
    MyItem(const MyItem& other) : name(other.name) {
        std::cout << "Copying " << name << std::endl;
    }
    // Оператор таъинкунии нусхабардорӣ
    MyItem& operator=(const MyItem& other) {
        if (this != &other) {
            name = other.name;
            std::cout << "Copy assigning " << name << std::endl;
        }
        return *this;
    }
    // Конструктор интиқол
    MyItem(MyItem&& other) noexcept : name(std::move(other.name)) {
        std::cout << "Moving " << name << std::endl;
    }
    // Оператор таъинкунии интиқол
    MyItem& operator=(MyItem&& other) noexcept {
        if (this != &other) {
            name = std::move(other.name);
            std::cout << "Move assigning " << name << std::endl;
        }
        return *this;
    }
    // Деструктор
    ~MyItem() {
        std::cout << "Destroying " << name << std::endl;
    }
};

int main() {
    std::vector<MyItem> items;
    items.reserve(2); // Захира кардани хотира барои 2 элемент

    items.emplace_back("item1"); // Бе reallocation
    items.emplace_back("item2"); // Бе reallocation

    std::cout << "Adding third item, triggering realloc-like operation:" << std::endl;
    items.emplace_back("item3"); // Талаб мекунад reallocation
    // Натиҷа нишон медиҳад интиқол барои item1 ва item2, пас аз он нобудсозии объектҳои кӯҳна
    // ва сохтани item3 нав.
    // Агар MyItem дастгирӣ намекард интиқолро, мебуд навишт о копиркунии.

    return 0;
}