Уютное сообщество С++ разработчиков
4.45K subscribers
94 photos
7 videos
96 links
Изучаем C++.
Ресурсы, обучения, задачи, шпаргалки.
Вопросы с собеседований по C++ и ответы на них.
Задачи и тесты по C++ для тренировки и обучения.
По рекламе: @anothertechrock
Download Telegram
int a = 5; int& b = a; b = 10; std::cout << a;
Anonymous Quiz
28%
5
61%
10
11%
Ошибка компиляции
0%
2
1🔥1👌1
Бросаем число
#новичкам

Мы привыкли, что исключения имеют какую-то свою иерархию и каждый класс имеет свое конкретное назначение в контексте отображения ошибки.

А что если мы попытаемся бросить что-то совсем несвязанное с иcключениями? Например, какой-нибудь тривиальный тип вроде int. Это вообще законно?

Абсолютно законно. В С++ можно бросать все, что угодно, кроме объектов неполных типов, абстрактных классов и указателей на неполный тип. Даже указатель на void можно.

Как и число.

Поймать число примерно также просто, как его бросить:

void foo() {
throw 1;
}

int main() {
try {
foo();
}
catch(int i) {
std::cout << i << std::endl;
}
}

// OUTPUT: 1


Это кстати один из любимых вопросов у интервьюеров.

"А можно ли кидать число вместо исключения?"

Теперь вы с полной уверенностью ответите "можно".

Но вот зачем это может быть нужно? Оставьте ваши мысли в комментариях

Make sense. Stay cool.

#interview #cppcore
👍1
🎲 Тест «Тест по C++»
Пройдите тестирование, проверьте свои знания с помощью онлайн тест-викторины C++, подготовьтесь к экзаменам по C++.
🖊 15 вопросов · 30 сек
👍21
👩‍💻 А вы уже работали с диапазонами?

В этом посте, я попробую объяснить базовые принципы диапазонов, поработаем с фильтрацией и преобразованием. Всё это используют чтобы улучшить читаемость и повысить эффективность работы с массивами в проектах.

- Фильтрация данных
- Трансформация данных
- Фильтрация и преобразование


Уютное сообщество С++ разработчиков | #гайд
👍21👌1
Современный C++ безопасное использование

Авторы: Джон Лакос, Витторио Ромео,
Ростислав Хлебников
Дата выхода: 2023

#cpp #ru

Скачать книгу
👍2
Что выведет следующий код и почему?

#include <iostream>

void foo(int a) { std::cout << "int"; }
void foo(char a) { std::cout << "char"; }

int main() {
foo(97);
return 0;
}


Ответ:
int

Почему?
Число 97 по умолчанию имеет тип
int, поэтому вызывается версия foo(int).
Если бы мы передали
'a' (символьный литерал), то вызвалась бы foo(char).

⚡️ Подвох: Если бы параметр был
unsigned char, то могла бы произойти неявная конверсия, но тут всё однозначно! 😊
👍6👌4
🤖 Пройди тест по C# ASP.NET Core и проверь свои знания, готов ли ты к обучению на курсе.

Ответишь — пройдешь на курс "C# ASP.NET Core разработчик" от OTUS по специальной цене + получишь доступ к записям открытых уроков курса

За 6 месяцев обучения вы научитесь решать задачи бэкенда и фронтенда, а также получите необходимые навыки работы с базами данных, UI, бизнес-логикой, настройками безопасности.

➡️ ПРОЙТИ ТЕСТ

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
А как вы пришли к программированию на плюсах?
Как это изменило вашу жизнь?
👍3😁2👌1
Потокобезопасный интерфейс
#новичкам

Не для всех очевидная новость: не всегда можно превратить класс из небезопасного в потокобезопасный, просто по уши обложившись лок гардами. Да, вызов конкретного метода будет безопасен. Но это не значит, что классом безопасно пользоваться.

Возьмем максимально простую реализацию самой простой очереди:

struct Queue {
void push(int value) {
storage.push_back(value);
}
void pop() {
storage.pop_front();
}
bool empty() {
return storage.empty();
}
int& front() {
return storage.front();
}
private:
std::deque<int> storage;
};


Она конечно потокоНЕбезопасная. То есть ей можно адекватно пользоваться только в рамках одного потока.

Как может выглядеть код простого консьюмера этой очереди?

while(condition)
if (!queue.empty()) {
auto & elem = queue.front();
process_elem(elem);
queue.pop();
}


И вот мы захотели разделить обязанности производителя чисел и их потребителя между разными потокам. Значит, нам надо как-то защищать очередь от многопоточных неприятностей.

Бабахаем везде лок гард на один мьютекс и дело в шляпе!

struct Queue {
void push(int value) {
std::lock_guard lg{m};
storage.push_back(value);
}
void pop() {
std::lock_guard lg{m};
storage.pop_front();
}
bool empty() {
std::lock_guard lg{m};
return storage.empty();
}
int& front() {
std::lock_guard lg{m};
return storage.front();
}
private:
std::deque<int> storage;
std::mutex m;
};


Все доступы к очереди защищены. Но спасло ли реально это нас?

Вернемся к коду консюмера:

while(true)
if (!queue.empty()) {
auto & elem = queue.front();
process_elem(elem);
queue.pop();
}



А вдруг у нас появится еще один консюмер? Тогда в первом из них мы можем войти условие, а в это время второй достанет последний элемент. Получается, что мы получим доступ к неинициализированной памяти в методе front.

То есть по факту в многопоточном приложении полученный стейт сущности сразу же утрачивает свою актуальность.

Что делать? Не только сами методы класса должны быть потокобезопасными. Но еще и комбинации использования этих методов тоже должны обладать таким свойством. И с данным интерфейсом это сделать просто невозможно.

Если стейт утрачивает актуальность, то мы вообще не должны давать возможность приложению получать стейт очереди. Нам нужны только команды управления. То есть push и pop.

struct ThreadSafeQueue {
void push(int value) {
std::lock_guard lg{m};
storage.push_back(value);
}
std::optional<int> pop() {
std::lock_guard lg{m};
if (!storage.empty()) {
int elem = storage.front();
storage.pop_front();
return elem;
}
return nullopt;
}
private:
std::deque<int> storage;
std::mutex m;
};


Внутри метода pop мы можем использовать проверять и получать стейт очереди, так как мы оградились локом. Возвращаем из него std::optional, который будет хранить фронтальный элемент, если очередь была непуста. В обратном случае он будет пуст.

Теперь консюмер выглядит так:

while(true) {
auto elem = queue.pop();
if (elem)
process_elem(elem.value());
}


Можно конечно было использовать кондвары и прочее. Но я хотел сфокусироваться именно на интерфейсе. Теперь реализация просто не позволяет получать пользователю потенциально неактульные данные.

Stay safe. Stay cool.

#concurrency #design #goodpractice
1
Самоучитель
"Уроки по C++"

Автор:
Ravesli
Год издания: 2022

#cpp #ru

Скачать книгу
👩‍💻 Вспоминаем методы для контейнеров!

В этом посте мы рассмотрим функции и методы для контейнеров. Они позволяют оптимизировать код, сокращая количество операций, и делают работу с контейнерами более удобной.

Уютное сообщество С++ разработчиков | #шпора
🔥31