Рубрика «c++» - 170

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

Как решать подобную задачу?Читать полностью »

Определения препроцессора (preprocessor definitions) часто используются в С++ проектах для условной компиляции выбранных участков кода, например, платформозависимых и т.п. В этой статье будут рассмотрены, видимо, единственные (но крайне сложные в отладке) грабли, на которые можно наступить при проставлении #define-ов через флаги компилятора.

В качестве примера возьмем систему сборки CMake, хотя те же действия можно совершить в любом другом ее популярном аналоге.
Читать полностью »

Прочитав статью «Вычислите длину окружности», которая, в общем-то, крайне позабавила меня своим стилем, и узнав для себя кое-что новое, я стал несколько сомневаться в достаточной подробности предложенной информации. Всё-таки компиляторов довольно много, систем тоже немало, а в статье как-то навеяно Windows и Visual Studio (на правах ИМХО).
Читать полностью »

Хорошо в плане поддержки JSON живётся программистам на Javascript — по какому-то невероятному стечению обстоятельств там JSON входит в спецификацию самого языка: есть JSON — есть объект. Удобно. Неплохо дело обстоит и в языках, где JSON не входит в сам язык, но поддерживается стандартной библиотекой (Python, Ruby): импортируешь модуль — и готово.

Жизнь программистов на С++ никогда не была особо простой — поддержки JSON у нас нет ни на уровне языка, ни в стандартной библиотеке. И не будет, возможно, никогда. «Тоже мне проблему нашел!» — скажут мне опытные коллеги — «Её там и не должно быть, С++ поставляется без „батареек“. Для решения этой задачи мы...» и вот здесь они разделятся на два лагеря:

1. «Мы используем большой фреймворк (boost, Qt, POCO, другой), который применяется во всех наших проектах и умеет 150 000 разных вещей, в том числе и JSON.»
2. «Мы придерживаемся подхода в котором для каждой задачи применяется своя легковесная библиотека. В частности, для JSON мы уже 150 000 лет назад выбрали отличную библиотеку %JSON_LIB%, которая прекрасно работает.»

Да, всё так и есть. Вот только…

Чем плох подход с использованием фреймворков

Во-первых, тянуть в проект огромный фреймворк ради одного JSON — как-то уныло. Ну ладно, допустим фреймворк у вас был и так. Но тогда придётся писать работу с JSON в терминах фреймворка, а это, как правило, тихий ужас. Посмотрите, например, на документацию по JSON в Qt — куча собственных типов вроде QJsonArray, QJsonDocument, QJsonObject, QJsonValue и т.д. и их придётся использовать. О том, чтобы потом перенести код в другой проект (где этого фреймворка нет) можно сразу забыть. Ну или вот Boost: парсер JSON находится очень логично в модуле Boost.PropertyTree. Ага, так бы я и догадался. Т.е. нам предлагают плясать не от формата JSON, а от структуры данных «дерево», которая умеет себя читать в том числе и из JSON.

В общем, фреймворки навязывают нам своё виденье задачи, свой способ её решения и стремятся навсегда привязать нас к себе. Нет, если вы уверены, что нашли тот самый единственный и неповторимый фреймворк и будете с ним счастливы до конца жизни — воля ваша. Но я как-то не сторонник подобного фатализма.

Чем плох подход с использованием библиотек

Плох он вот этой частью: "...150 000 лет назад выбрали отличную библиотеку...". Скорее всего речь идёт о чём-то, что начинало писаться чуть-ли не во времена DOSа и, без сомнения, работает, но при этом, пытаясь быть совместимым со всеми платформами и стандартами языка совершенно отстаёт от прогресса. Да, всё компилируется и работает, даже тесты проходит. Но библиотека совершенно не знакома с такими вещами, как ключевое слово auto, range-based циклы, строковые литералы, raw-строки, конструкторы перемещения, списки инициализации и прочие классные вещи, делающие код одновременно более эффективным и более легко читаемым. А ведь у библиотеки, созданной годы назад, есть обязательства по обратной совместимости, а значит просто так взять и добавить это всё она не может.

Давайте немного помечтаем.

А что, если бы JSON вошел в стандартную библиотеку нового стандарта С++? Что, если бы он был написан в терминах С++1114 и без требований обратной совместимости со старыми стандартами языка? Что, если бы синтаксис этого модуля попытались бы сделать максимально приближенным к родному для JSON использованию «а-ля Javascript», но в том же время сохранить дух С++ (эффективность, минимальное потребление памяти, совместимость с STL)? Что, если бы его можно было включить в проект одним инклюдом и не беспокоиться о его сборке и линковке? Как бы это всё выглядело и работало?

И у нас есть ответ на этот вопрос! Давайте посмотрим на JSON-библиотеку для С++ написанную в соответствии со всеми этими принципами, ну и вообще написанной людьми для людей, а не чужими для хищников, как это обычно бывает.
Читать полностью »

Давайте придумаем решение вот такой-вот простенькой задачи.
Имеется: браузер (IE, Chrome или Firefox), уже запущенный пользователем.
Требуется: написать программу, которая получит URL, который в данный момент введён в адресной строке.

Давайте подумаем, каким образом эту простенькую задачу решить НЕ получится:

1. FindWindow + GetWindowText

Почему не получится

Первая идея — найти окно браузера, в нём дочернее окно адресной строки и взять URL оттуда. Практика показывает, что отдельное дочернее окно для адресной строки имеет только IE. FF и Chrome кросплатформенны, поэтому предпочитают весь свой контент отрисовывать самостоятельно.

2. Браузерное расширение, которое отдаст URL нашей программе (например, через запрос к localhost)

Почему не получится

Можно. Но во-первых, для трёх браузеров нужно будет написать 3 разных расширения, а во-вторых, для FF и Chrome мы будем вынуждены распространять его только через их магазины расширений. Писать программу, работоспособность которой зависит от того, зачешется ли сегодня левая пятка модератора — нет уж, увольте.

3. Давайте напишем сниффер и посмотрим что там пользователь открывал

Почему не получится

А давайте! Но что дальше? Даже если из потока трафика мы выделим данные, полученные именно браузером и расшифруем HTTP-протокол, мы всё-равно не узнаем именно текущий URL (ссылок в потоке будет много). Кроме того, сразу идут в сад HTTPS-соединения, HTTP/2, ссылки на локально открытые файлы, ссылки на внутренние страницы (типа chrome://settings) и т.д.

4. Давайте воспользуемся Remote Debugging Protocol ну или каким-нибудь Selenium-ом

Почему не получится

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

5. Может быть, хуки?

Почему не получится

Ну, внедриться-то мы в браузер сможем. А на что вешать хуки? Для IE всё ясно — SetWindowText для окна адресной строки (но с ним и более простой способ №1 проходил). А в FF и Chrome у нас нет каких-то чётко определённых объектов и интерфейсов, на которые мы можем завязаться. Можно что-то сделать с конкретной версией браузера, но универсального решения не получится.

6. Скриншот окна браузера, определение положения адресной строки, распознавание текста с картинки!

Почему не получится

Уже как-то начинает смахивать на отчаяние, правда? Прикинем все варианты цветовых схем ОС, разрешений, масштабов, учтём наличие в браузере плагинов, цветовых схем, нестандартного расположения элементов, right-to-left языковых локалей ну и закончим случаем, когда окно адресной строки слишком узкое, чтобы вместить URL полностью.

7. Ваш вариант
А напишите в комментариях, какие ещё решения вам приходят в голову и мы подумаем, получится или нет.

А теперь один из правильных ответов: мы воспользуемся уже старенькой, но весьма стабильной и поддерживаемой всеми браузерами во всех ОС с Win95 до Win10 технологией Microsoft Active Accessibility, которая даст нам возможность не только получить текущий URL (при чём одинаковым образом для всех браузеров), но и вообще дать доступ ко всему контенту браузера — от самого родительского окна с его заголовком, меню, тулбаром, вкладками и до содержимого открытой веб-страницы вплоть до самого последнего её элемента.
Читать полностью »

Наверняка все знают прописную (в книгах про С++) истину о чудесной методологии RAII, если нет — приведу краткое описание из википедии.

Это шаблонное описание этой техники

Получение ресурса есть инициализация (англ. Resource Acquisition Is Initialization (RAII)) — программная идиома объектно-ориентированного программирования, смысл которой заключается в том, что с помощью тех или иных программных механизмов получение некоторого ресурса неразрывно совмещается с инициализацией, а освобождение — с уничтожением объекта.

Типичным (хотя и не единственным) способом реализации является организация получения доступа к ресурсу в конструкторе, а освобождения — в деструкторе соответствующего класса. Поскольку деструктор автоматической переменной вызывается при выходе её из области видимости, то ресурс гарантированно освобождается при уничтожении переменной. Это справедливо и в ситуациях, в которых возникают исключения. Это делает RAII ключевой концепцией для написания безопасного при исключениях кода в языках программирования, где конструкторы и деструкторы автоматических объектов вызываются автоматически, прежде всего — в C++.

Последнее предложение вроде как обещает 100% гарантию результата, но как всегда в жизни, а особенно в С++, есть ньюанс.
Читать полностью »

Привет, меня зовут Дмитрий, программист из Snowforged Entertainment. Я только что закончил рефакторинг компонента движения кораблей для проекта Starfall Tactics — тактической игры в реальном времени, в которой игроки могут собрать свой собственный космический флот и повести его в бой. Компонент движения переписывался уже три раза, от релиза до начала разработки альфа версии. Было собрано множество граблей, как архитектурных, так и сетевых. Постараюсь подбить весь этот опыт и рассказать вам о: Navigation Volume, Movement component, AIController, Pawn.
Читать полностью »

Чтобы не перегружать данную статью, разобью ее на 2 части:

1. Постановка задачи и методы реализации;
2. Программное распознавание и электроника.

Инженер

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

Через некоторое время я получил задачу в любимом для многих свободном формате. Мне было позволено пофантазировать на эту тему и через некоторое время предоставить свои «мисли» по этому поводу.
Читать полностью »

Intel® RealSense™. Работа с потоками необработанных данных - 1
Разработчикам, которые интересуются возможностями, доступными при внедрении управления без помощи контроллеров в своих приложениях, достаточно ознакомиться с Intel RealSense SDK, сопутствующими примерами и ресурсами в Интернете. Если вы «погрузитесь» в это решение, то обнаружите широкий набор функций, позволяющих создавать совершенно новые, великолепные интерфейсы с использованием новых технологий.
В этой статье мы поговорим о потоках различных необработанных данных, о доступе к ним и о способах их использования. За счет прямого доступа к необработанным данным мы не только сможем работать с метаданными, но и получим самый быстрый способ определять, что делает пользователь в реальном мире.
Читать полностью »

Администрирование глазами C++ программиста - 1 Продолжаем цикл пятничных статей "X глазами C++ программиста" (1, $$). В этот раз под катом вас ждут впечатления заядлого С++ программиста от мира администрирования. Боль, страдания, радости и прочие эмоции как всегда вынесены под спойлеры.

Надеюсь будет интересно профессиональным администраторам посмотреть на потуги С++ника, ну а С++ разработчикам узнать для себя что-то новое.
Читать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js