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;
}