С++ для интервью
37 subscribers
10 photos
Готовься к собеседованиям по C++ эффективно: реальные вопросы, типичные HR уловки, примеры кода и объяснения.
Каждый пост — один шаг ближе к офферу 💼
Download 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 — Как работает частичная специализация
⚙️ Type Traits: когда типы становятся логикой

Примеры Type Traits
template<typename T>
struct is_pointer
{
static constexpr bool value = false;
};

template<typename T>
struct is_pointer<T*>
{
static constexpr bool value = true;
};

assert(is_pointer<int*>::value);


🧠 Type Traits — шаблонные конструкции, которые предоставляют информацию о свойствах типов во время компиляции
Используются в std::enable_if, concepts, std::move.
Какой trait определяет, является ли тип числовым?
Anonymous Poll
0%
std::is_arithmetic
0%
std::is_integral
100%
std::is_numeric
🎯 Policy-based Design: шаблонная настройка поведения

Пример реализации:
template<typename ThreadPolicy, typename LogPolicy>
class Engine : private ThreadPolicy, private LogPolicy
{
public:
void run()
{
this->log("Starting...");
this->lock();
this->unlock();
}
};


✅ Вместо наследования от суперкласса составляем объект из политик, что позволяет легко менять поведение без лишнего кода.