🧠 Задача с подвохом для продвинутых C++ разработчиков
🔹 Уровень: Advanced
🔹 Темы:
📌 Условие
Рассмотрим следующий код:
❓ Вопросы
1. Что будет выведено на экран?
2. Почему
3. Что изменится, если заменить
🔍 Разбор
✅ Ожидаемый вывод:
🔧 Почему так происходит
-
-
- Временный объект уничтожается (вызывается `Dtor`).
-
🔄 Если заменить `reserve(3)` на `resize(3)`
-
-
- Это может привести к копированию или перемещению уже созданных элементов.
⚠️ Подвох
Многие ошибочно считают, что
🧠 Вывод
-
-
- Не путай эти методы — от этого зависит и производительность, и семантика.
📌 Совет:
Если не хочешь лишнего перемещения, используй
🔹 Уровень: Advanced
🔹 Темы:
std::vector, управление памятью, конструкторы/деструкторы, reserve() vs resize()📌 Условие
Рассмотрим следующий код:
#include <iostream>
#include <vector>
struct Foo {
Foo() { std::cout << "Ctor\n"; }
~Foo() { std::cout << "Dtor\n"; }
Foo(const Foo&) { std::cout << "Copy\n"; }
Foo(Foo&&) noexcept { std::cout << "Move\n"; }
};
int main() {
std::vector<Foo> v;
v.reserve(3); // Резервируем место под 3 элемента
std::cout << "--- Pushing ---\n";
for (int i = 0; i < 3; ++i) {
v.push_back(Foo());
}
std::cout << "--- Done ---\n";
}
❓ Вопросы
1. Что будет выведено на экран?
2. Почему
reserve() не предотвращает конструкторы копирования/перемещения? 3. Что изменится, если заменить
reserve(3) на resize(3)?🔍 Разбор
✅ Ожидаемый вывод:
--- Pushing ---
Ctor
Move
Dtor
Ctor
Move
Dtor
Ctor
Move
Dtor
--- Done ---
Dtor
Dtor
Dtor
🔧 Почему так происходит
-
Foo() создаёт временный объект. -
push_back() вызывает перемещающий конструктор Move. - Временный объект уничтожается (вызывается `Dtor`).
-
reserve(3) выделяет память, но не создаёт объектов.🔄 Если заменить `reserve(3)` на `resize(3)`
-
resize(3) создаст 3 объекта Foo через конструктор по умолчанию. -
push_back(Foo()) добавит четвёртый, возможно вызовет realocation. - Это может привести к копированию или перемещению уже созданных элементов.
⚠️ Подвох
Многие ошибочно считают, что
reserve(n) создаёт n объектов. Но это не так — reserve() только выделяет память, не вызывая конструкторы. Именно поэтому внутри push_back всё равно происходит перемещение или копирование.🧠 Вывод
-
reserve() — экономия на реаллокациях, без создания объектов. -
resize() — создаёт n объектов, вызывает конструкторы. - Не путай эти методы — от этого зависит и производительность, и семантика.
// Резервирует память, не создаёт объекты
v.reserve(10);
// Создаёт 10 объектов Foo
v.resize(10);
📌 Совет:
Если не хочешь лишнего перемещения, используй
emplace_back():
v.emplace_back(); // Вызывает конструктор Foo напрямую внутри вектора
👍6❤1
Что произойдёт при использовании std::variant?
Anonymous Quiz
13%
Исключение std::bad_variant_access
20%
Ошибка компиляции
61%
test
6%
Неопределённое поведение
👍3❤1
Какое главное отличие std::map от std::unordered_map?
Anonymous Quiz
6%
std::map использует меньше памяти
84%
std::unordered_map не гарантирует порядок элементов
5%
std::map быстрее для операций поиска
4%
std::unordered_map не поддерживает сложные ключи