Middle
realloc ოპერაციის დროს std::vector ელემენტებთან რა ხდება?
sobes.tech AI
პასუხი AI-სგან
std::vector realloc-ды колдонбойт. Контейнердин өлчөмү өзгөргөндө, ал кайра бөлүштүрүү талап кылынганда, төмөнкүлөр болот:
- Жаңы эс тутум бөлүнөт.
- Элементтер эски бөлүмдөн жаңы бөлүмгө которулат:
- Тартиптер үчүн, алар которуу семантикасын колдошот (
Tтуура ишке ашырылган которуу конструктору жана/же которуу тағайындау оператору менен), которуу колдонулат. Бул натыйжалуу, анткени эски ресурстар (мисалы, объекттердин ичинде бөлүнгөн эс тутум) жаңы объекттерге өткөрүлүп берилет, жана эски объекттер жарактуу, бирок белгисиз абалда калат же деструкторлор менен тазаланады. - Которуу семантикасын колдобогон типтер үчүн же эгер компилятор которууну колдонууга мүмкүнчүлүк бербесе, көчүрүү колдонулат.
- Эгер элементтер тривиалдуу көчүрүлө турган болсо (
TPOD тип же тривиалдуу көчүрүү жана которуу операциялары бар),memcpyже башка төмөн деңгээлдеги функциялар колдонулушу мүмкүн.
- Тартиптер үчүн, алар которуу семантикасын колдошот (
- Эски бөлүмдөгү элементтердин деструкторлору чакырылат.
- Эски бөлүмдөгү эс тутум бошотулат.
Маанилүү: эски бөлүмдөгү көрсөткүчтөр жана шилтемелер кайра бөлүштүрүүдөн кийин жараксыз болот.
#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;
}