Middle
realloc operatsiyasi davomida std::vector elementlari bilan nima bo'ladi?
sobes.tech AI
AIdan javob
std::vector realloc-ni ishlamaydi. Kapsaytirilgan hajmi o'zgartirilganda, xotira qayta taqsimlanishini talab qiladigan holatda, quyidagilar yuz beradi:
- Yetarli o'lchamdagi yangi xotira maydoni ajratiladi.
- Eski maydondagi elementlar yangi maydonga ko'chiriladi.
- Agar turlar harakat qilish semantikasi (
Tto'g'ri amalga oshirilgan harakat qilish konstruktor va/yoki harakat qilish tayinlash operatori bilan)ni qo'llab-quvvatlasa, harakat qilish ishlatiladi. Bu yanada samarali, chunki eski resurslar (masalan, ob'ekt ichida ajratilgan xotira) yangi ob'ektlarga o'tkaziladi va eski ob'ektlar valid holatda qoladi yoki destruktorlar bilan tozalanadi. - Harakat qilish semantikasi qo'llab-quvvatlamaydigan turlar yoki kompilator harakat qilishni qo'llay olmasa, nusxa ko'chirish ishlatiladi.
- Elementlar trivially nusxa ko'chiriladigan bo'lsa (
TPOD tur yoki trivially nusxa ko'chirish va harakat qilish operatsiyalari bilan),memcpyyoki shunga o'xshash past darajadagi funksiyalar yordamida xom ma'lumotlar tezda nusxa ko'chirilishi mumkin.
- Agar turlar harakat qilish semantikasi (
- Eski xotira maydonidagi elementlar uchun destruktorlar chaqiriladi.
- Eski xotira maydoni bo'shatiladi.
Muhim: eski maydondagi elementlarga ishora qiluvchi ko'rsatkichlar va referenslar, qayta taqsimlashdan so'ng, amal qilishdan to'xtaydi.
#include <vector>
#include <iostream>
#include <string>
struct MyItem {
std::string name;
// Konstruktor
MyItem(const std::string& n) : name(n) {
std::cout << "Constructing " << name << std::endl;
}
// Nusxa ko'chirish konstruktor
MyItem(const MyItem& other) : name(other.name) {
std::cout << "Copying " << name << std::endl;
}
// Nusxa tayinlash operatori
MyItem& operator=(const MyItem& other) {
if (this != &other) {
name = other.name;
std::cout << "Copy assigning " << name << std::endl;
}
return *this;
}
// Harakat qilish konstruktor
MyItem(MyItem&& other) noexcept : name(std::move(other.name)) {
std::cout << "Moving " << name << std::endl;
}
// Harakat qilish tayinlash operatori
MyItem& operator=(MyItem&& other) noexcept {
if (this != &other) {
name = std::move(other.name);
std::cout << "Move assigning " << name << std::endl;
}
return *this;
}
// Destruktor
~MyItem() {
std::cout << "Destroying " << name << std::endl;
}
};
int main() {
std::vector<MyItem> items;
items.reserve(2); // 2 ta element uchun ajratish
items.emplace_back("item1"); // reallocsiz
items.emplace_back("item2"); // reallocsiz
std::cout << "Uchinchi element qo'shilmoqda, reallocga o'xshash operatsiya chaqirilmoqda:" << std::endl;
items.emplace_back("item3"); // realloc talab qilinadi
// Chiqarish, item1 va item2 uchun harakatni, eski ob'ektlarning destruksiyasini va yangi item3 konstruktsiyasini ko'rsatadi.
// Agar MyItem harakat qilishni qo'llab-quvvatlamasa, nusxa ko'chirish ko'rsatiladi.
return 0;
}