Где здесь ошибка в RAII-классе?
Anonymous Poll
0%
Всё корректно
100%
Нужно объявить delete для конструктора копирования
100%
Нужно проверить f перед fclose
0%
Нельзя копировать объект
Кроме того, копирование File приведёт к двойному закрытию — класс должен быть не копируемым, а перемещаемым.
Please open Telegram to view this post
VIEW IN TELEGRAM
В чём суть идиомы RAII?
Anonymous Quiz
50%
Обеспечивает освобождение ресурсов в деструкторе
25%
Автоматически оптимизирует память
25%
Гарантирует потокобезопасность
0%
Ускоряет выполнение кода
Почему RAII-объект часто имеет move, но не copy?
Anonymous Quiz
0%
Чтобы избежать утечек при исключениях
33%
Чтобы можно было передавать владение ресурсом
33%
Чтобы избежать дорогостоящего копирования
33%
Просто потому что это современный стиль
Когда вызовется ~Socket()?
Anonymous Quiz
40%
Сразу после выброса исключения
20%
После catch-блока
20%
Никогда
20%
Зависит от оптимизаций компилятора
Что делает объект ScopeExit guard([]{ unlock(); }) ?
Anonymous Quiz
0%
Вызывает unlock() сразу при создании
100%
Вызывает unlock() при выходе из области видимости
0%
Вызывает unlock() при перемещении
0%
Не вызывает ничего
🧩 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
Пояснение: Зависимости — от абстракций, а не от конкретных реализаций.
Пример: Использование родительского класса для создания экземпляра —
⚙️ Пример использования SOLID
— SRP:
— OCP: можно добавить
— LSP: любой
— ISP: интерфейс компактный.
— DIP: зависимости через абстракции.
Подводя итог, SOLID — набор основных принципов, позволяющих писать читаемый, тестируемый и расширяемый C++ код.
#cpp_tips
Что такое 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 — это шаблон, где класс-наследник передаёт себя в качестве параметра шаблона базовому классу.
А наследник выглядит так:
⚙️ Как это работает
Когда ты вызываешь:
Базовый класс вызывает метод
при этом без виртуальных функций — всё статически известно на этапе компиляции.
🚀 Где это полезно:
— Mixin — добавление поведения к классам без виртуальности.
— Policy-based design — подмена стратегий через шаблонные параметры.
— Статический полиморфизм — альтернатива
— Ограничение интерфейса наследников — например, через
🧠 Пример Mixin с CRTP
— Без virtual
— Без динамической памяти
— Гибко и эффективно
В итоге имеем:
CRTP — способ реализовать полиморфизм, заменив виртуальные вызовы статическим связыванием на этапе компиляции.
#cpp_tips
Как использовать шаблоны, а не виртуальность, чтобы дать базовому классу знать о потомке?
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
Что выведет программа
Anonymous Quiz
50%
General
50%
Int second
0%
Ошибка компиляции
0%
Неопределенное поведение
⚙️ Type Traits: когда типы становятся логикой
Примеры Type Traits
🧠 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();
}
};
✅ Вместо наследования от суперкласса составляем объект из политик, что позволяет легко менять поведение без лишнего кода.