reinterpret_cast
. Это выстрел себе в ногу.reinterpret_cast
работает очень коварно:Unlike static_cast, but like const_cast, the reinterpret_cast expression does not compile to any CPU instructions... It is purely a compile-time directive which instructs the compiler to treat expression as if it had the type new_type.
static_cast
- этого тут достаточно для работы. Этот каст приведет this
к правильному указателю на объект родительского типа. Насколько это правильно?
SocketOutputStream
не собирает твои данные в единый бинарный буфер, а сразу пишет их в сокет. Это дает волю кому угодно вклиниться из другого потока в этот сокет между операциями записи в твоем текущем потоке. Т.е. транзакция записи сообщения может быть легко нарушена.flush
при этом - это барьер синхронизации между исполнением твоего кода и очисткой конвейера операций устройства (в самом устройстве). В случае блокируемых сокетов flush
- фиктивная штука.SocketOutputStream
. Т.е. передавай на запись в сокет не сообщение, а буфер, куда сообщение сериализовано.std::vector<int>{10}
: вектор с одним элементом или с десятью?vector<int> arr(10)
?Stack
?
Logger.log('старт скрипта')
- это что, каждую функцию так начинать и заканчивать?Logger.log('Нормально все прошло идем дальше')
- это ты в каждом удобном месте писать хочешь?Так недолго и замучить себя нудным репитативом, а еще так очень легко размыть код алгоритма и код поддержки/обеспечения алгоритма. На питоне я бы тебе посоветовал использовать декоратор для автоматической вставки логов в начало и конец функции, а для трассировки этапов функции хорошо бы подошел контекстный менеджер.
Посмотри как такие декораторы пишутся и как работают. Например так (мной не очень любимая форма), или вот так, что мне нравится больше. И про контекстные менеджеры тоже примеры есть.
И исключения в таком стиле обрабатывать удобнее. Проверено.
Безусловно,
Logger.log
прямо так брать и списывать не стоит, он тоже полезный и им тоже важно пользоваться. Но не для трассировки.