С++ для интервью
37 subscribers
10 photos
Готовься к собеседованиям по C++ эффективно: реальные вопросы, типичные HR уловки, примеры кода и объяснения.
Каждый пост — один шаг ближе к офферу 💼
Download Telegram
⌨️ Рассмотрим несколько способов создания экземпляра класса. В компаниях используют разный код стайл. Поэтому важно знать все возможные способы.

⚠️ Самый последний способ не будет компилироваться, так как перестановка полей для инициализации класса не допустима.

struct Entity 
{
int x = 0, y = 0;
};

int main()
{
Entity entity_1;
Entity entity_2(2);
Entity entity_3(3, 3);
Entity entity_4 { .x = 4 };
Entity entity_5 { .x = 5, .y = 5 };
Entity entity_6 { .y = 6 };
// Entity entity_7 { .y = 7, .x = 7 }; // error
}

#cpp_tips
Please open Telegram to view this post
VIEW IN TELEGRAM
📦 Рассмотрим важный концепт языка C++. Move semantics.

💭Основная идея:
Копировать дорого. Перемещать — почти бесплатно


Современный C++ , начиная с C++11, позволяет не копировать объекты,
а просто передавать владение ресурсом. Это и есть move semantics.

std::string a = "Hello";
std::string b = a; // копирование
std::string c = std::move(a); // перемещение


📋 Копирование → создаёт новую строку, копирует все символы.
🚚 Перемещение → "забирает" указатель у a, а a становится пустой.

⚠️ std::move — это не move, это cast
🧠 std::move не перемещает ничего сам по себе!
Он лишь превращает объект в rvalue-ссылку,
давая компилятору понять:
Я больше не буду использовать этот объект — можешь забирать ресурсы.

❗️Важное правило: после std::move — не трогай объект

std::string s = "Hello";
auto t = std::move(s);
std::cout << s; // ❌


❓ Когда использовать std::move

✅ Возврат временного объекта из функции:

std::string make() {
std::string s = "Data";
return s; // RVO или move
}


✅ При передаче в контейнер:

vec.push_back(std::move(obj));


🚫 Не используем при передаче по const& — const запрещает move!

void f(const std::string& s) {
auto t = std::move(s); // ❌ всё равно копия
}


🎯 Что мы имеет в итоге:

1️⃣ std::move — это rvalue cast, не “перемещение”.

2️⃣ Move-конструктор переносит ресурсы, оставляя источник “пустым”.

3️⃣ После move объект можно уничтожать, но не использовать.

4️⃣ const запрещает move.

Пользуйтесь, друзья, и делитесь со своими товарищами программистами 🤝

#cpp_tips #cpp_question
Please open Telegram to view this post
VIEW IN TELEGRAM
Найдите все ошибки данной реализации структуры в рамках RAII
💡 Правильный ответ: 2 и 3

🤓 Пояснения: Если fopen вернул nullptr, fclose(nullptr) — UB.
Кроме того, копирование File приведёт к двойному закрытию — класс должен быть не копируемым, а перемещаемым.
Please open Telegram to view this post
VIEW IN TELEGRAM
Что произойдёт при исключении в конструкторе?
Что делает такой шаблон RAII-защитника?
🧩 SOLID-принципы C++

Что такое SOLID и для чего он необходим?

1️⃣ S — Single Responsibility

Пояснение:
Класс делает узконаправленную задачу
Пример: Logger не должен писать в базу.

2️⃣ O — Open/Closed

Пояснение: Код открыт для расширения, но закрыт для модификации.
Пример: Использование виртуальных функций, шаблонов, полиморфизма.

3️⃣ L — Liskov Substitution

Пояснение:
Объекты подклассов можно использовать вместо базовых.
Пример: Если Derived ломает контракт Base, нарушен LSP.

4️⃣ I — Interface Segregation

Пояснение: Лучше несколько маленьких интерфейсов, чем один общий.

5️⃣ D — Dependency Inversion

Пояснение: Зависимости — от абстракций, а не от конкретных реализаций.
Пример: Использование родительского класса для создания экземпляра — unique_ptr<IService> вместо unique_ptr<MyService>.

⚙️ Пример использования SOLID

struct IShape {
virtual double area() const = 0;
virtual ~IShape() = default;
};

class Circle : public IShape {
double r_;
public:
explicit Circle(double r) :
r_(r) {}

double area() const override
{
return 3.14 * r_ * r_;
}
};


— SRP: Circle отвечает только за площадь круга.
— OCP: можно добавить Rectangle, не меняя IShape.
— LSP: любой IShape заменим на Circle.
— ISP: интерфейс компактный.
— DIP: зависимости через абстракции.

Подводя итог, SOLID — набор основных принципов, позволяющих писать читаемый, тестируемый и расширяемый C++ код.

#cpp_tips
🧬 CRTP (Curiously Recurring Template Pattern)

Как использовать шаблоны, а не виртуальность, чтобы дать базовому классу знать о потомке?


CRTP — это шаблон, где класс-наследник передаёт себя в качестве параметра шаблона базовому классу.

template <typename Derived>
class Base
{
public:
void interface()
{
static_cast<Derived*>
(this)->implementation();
}
};


А наследник выглядит так:

class Derived : public Base<Derived>
{
public:
void implementation()
{
std::cout << "Derived func\n";
}
};


⚙️ Как это работает

Когда ты вызываешь:

Derived d;
d.interface();


Базовый класс вызывает метод implementation() у конкретного типа Derived,
при этом без виртуальных функций — всё статически известно на этапе компиляции.

🚀 Где это полезно:

— Mixin — добавление поведения к классам без виртуальности.

— Policy-based design — подмена стратегий через шаблонные параметры.

— Статический полиморфизм — альтернатива virtual, но без runtime overhead.

— Ограничение интерфейса наследников — например, через enable_if и SFINAE.


🧠 Пример Mixin с CRTP

template <typename Derived>
class Printable
{
public:
void print() const
{
std::cout <<
static_cast<const Derived*>
(this)->toString();
}
};

class Point : public Printable<Point>
{
public:
Point(int x, int y) : x_(x), y_(y) {}
std::string toString() const
{
return std::to_string(x_) + ","
+ std::to_string(y_);
}
private:
int x_, y_;
};


Point p(2, 3);
p.print(); // 2,3


— Без virtual
— Без динамической памяти

— Гибко и эффективно

В итоге имеем:
CRTP — способ реализовать полиморфизм, заменив виртуальные вызовы статическим связыванием на этапе компиляции.

#cpp_tips
🧩 Тест 1 — Как работает вывод типов шаблона
Что выведет программа
Anonymous Quiz
0%
int
0%
double
100%
Ошибка компиляции
0%
auto
⚙️ Тест 2 — Передача по ссылке и вывод типов
Какой тип будет у T
Anonymous Quiz
0%
int
100%
const int
0%
int &
0%
const int &
🧩 Тест 3 — Как работает частичная специализация