Ответы пользователя по тегу C++
  • Какую литературу приобрести?

    Nipheris
    @Nipheris Куратор тега C++
    1) линейная алгебра и выч. геометрия;
    2) начала комп. графики: www.amazon.com/Fundamentals-Computer-Graphics-Pete...
    3) конкретно по OpenGL: www.amazon.com/OpenGL-Programming-Guide-Official-L...
    4) книгу по механике, ну или главы по механике из учебника по физике для ВУЗов;
    5) по звуку книгу не подскажу, современные звуковые API для игр и прочей виртуальной реальности (т.е. где важна поддержка 3D) - OpenAL (кроссплатформеное), XAudio2 (винда).
    Ответ написан
    Комментировать
  • Адреса указателей?

    Nipheris
    @Nipheris Куратор тега C++
    Потому что указатели - прежде всего такие же переменные, как и любые другие (это очень важно понимать). Второе выведенное значение - это значение переменной b, и не особо важно, указатель это или нет (в нашем случае - да, указатель, и поэтому выведенное значение переменной b - некоторый адрес). Третье выведенное значение - это АДРЕС переменной b, и не имеет значения, что за тип у переменной b. Вы можете объявить int b или float b, и получите аналогичный результат.

    Вот что является отличительным моментом указателя - это как раз таки первое выведенное значение, а точнее, сама возможность его вывести. Для указателей (а также для любых пользовательских типов, реализующих operator*) доступна операция разыменования. Это дает возможность взять значение переменной b, интерпретировать его как адрес, а затем, в свою очередь, залезть в память по этому адресу и получить значение уже оттуда. В данном случае можно утверждать, что по адресу 0x011CD1C0 находится значение 66 (если его интепретировать соответственно типу указателя).
    Ответ написан
    1 комментарий
  • Как корректно обрезать строку тип string в utf8 на с++?

    Nipheris
    @Nipheris Куратор тега C++
    ICU
    Ответ написан
    Комментировать
  • Чем заменить x11Info при переходе на qt5?

    Nipheris
    @Nipheris Куратор тега C++
    В целом, заменить можно на QDesktopWidget , но придется как-то уйти от использования класса Display, указатель на объект которого возвращается методом display(). Нужно разбираться, что за функция XRRGetScreenInfo, и как она этим Display пользуется. Возможно, будет достаточно свойства primaryScreen для получения номера главного экрана и метода screenGeometry(int screen).
    Ответ написан
    Комментировать
  • Как использовать общие переменных в многопоточных программах с++?

    Nipheris
    @Nipheris Куратор тега C++
    Ну начнем с того, что 10000 итераций на современном процессоре выполнится настолько быстро, что вероятно уложится в отведенный потоку квант времени, и второй поток скорее всего даже не успеет получить процессорное время, чтобы поменять вашу переменную. Поэтому ИСКЛЮЧИТЕЛЬНО в целях эксперимента можете попробовать увеличить число итераций хотя бы до 10 миллионов, и отключить по максимуму оптимизации (не по причине скорости, а по причине потенциального выбрасывания кода компилятором), т.к. наверняка количество итераций есть причина неудачи в вашем эксперименте.

    А если по-серьезному, вам уже дали советы как поступать - без нормальной синхронизации в многопоточной среде у вас никакие общие переменные результатов дать не могут. Если уж очень не хочется брать мьютекс (хотя чтобы его не брать, нужно четко знать что он не подходит), можете превратить вашу общий флажок в спинлок, но кодом на плюсах тут не отделаешься.

    С архитектурной точки зрения, если у вас снятие показаний, то у вас просто классический случай producer-consumer - впилите потокобезопасную очередь, и пользуйтесь.
    Ответ написан
    3 комментария
  • SQLite FTS5 usage, what does xToken() do in xTokenize()?

    Nipheris
    @Nipheris Куратор тега C++
    В https://sqlite.org/fts5.html#section_7_1 ясно написано:


    xTokenize:
    This function is expected to tokenize the nText byte string indicated by argument pText. pText may or may not be nul-terminated. The first argument passed to this function is a pointer to an Fts5Tokenizer object returned by an earlier call to xCreate().
    ..........
    For each token in the input string, the supplied callback xToken() must be invoked.

    ВЫ пишете тройку функций xCreate, xDelete, xTokenize. При вызове вашей xTokenize ей будет передан колбэк, который, как правильно подметил abcd0x00 , нужно будет дергать для передачи движку SQLite готовой (т.е. подготовленной ВАМИ в процессе работы xTokenize) лексемы. Они называют это токен, но вообще это лексема, т.к. вы отдаете кусок из входной строки.
    Итого, все максимально просто - вам дается строка, вы по своим алгоритмам и критериям решаете, где в ней какие лексемы. Для каждой найденной лексемы дергаете данный вам xToken, чтобы сообщить эту радостную новость SQLite.
    Обязаны ли мы его вызывать?

    нет, но если не будете вызывать, ни одной лексемы из входной строки SQLite не получит.
    Если его должны реализовать мы

    его реализует SQLite.
    Ответ написан
    1 комментарий
  • C++ сеть. Как работать с сетью в C++?

    Nipheris
    @Nipheris Куратор тега C++
    Знаю что есть библиотеки ACE, POCO, BOOST(гуглил), но ничего про них не знаю больше.

    ну так узнайте! Узнайте про Boost::Asio, узнайте про cpp-netlib, построенную поверх него (как раз будет вам HTTP клиент и сервер)
    Ответ написан
    Комментировать
  • Каким способом реализовать на канвасе "зум" например от года к конкретному дню недели?

    Nipheris
    @Nipheris Куратор тега C++
    А чего тут думать. Ну введите некое условное обозначение зума, например 1 - это минимальное увеличение, как сейчас. Также введите точку - центр viewport-а, куда смотрит пользователь. В зависимости от значения масштаба, отрисовывать дни/часы или минуты. Отрисовывать только то, что видно через вьюпорт. Таким образом у вас получится длинный-предлинный календарь, в каждый момент времени вы будете видеть лишь его фрагмент. Ну как тайловых картах сделано.
    Ответ написан
    Комментировать
  • Где лучше включать заголовочные файлы?

    Nipheris
    @Nipheris Куратор тега C++
    К teugen добавлю, что если вы используете не значение класса/структуры, а указатель на него, то в хедер вместо инклуда другого хедера можно вставить объявление класса:

    #pragma once
    class ExampleClass;
    class MyClass {
    public:
     ExampleClass* ExampleFunction();
    };

    а инклуд определения класса делать там, где без него уже никак - например там, где вызываются методы класса или создаются его экземпляры.
    Ответ написан
    2 комментария
  • Аналог QStringBuilder для ванильного с++. Где взять?

    Nipheris
    @Nipheris Куратор тега C++
    std::stringstream

    По поводу "лишнего выделения памяти" - это надо брать реализации и сравнивать (т.е. не могу сказать насколько QStringBuild лучше/хуже std::stringstream), но, как говорится, look&feel почти такой же. Вместо процентиков поставьте <<, а потом вызовите .str()
    Ответ написан
    6 комментариев
  • Как правильно перевести из 16СС в 2СС?

    Nipheris
    @Nipheris Куратор тега C++
    В дополнение к MiiNiPaa скажу, что все ваши числа и так хранятся в двоичной системе счисления, сегодняшняя популярная выч. техника с другими системами не работает. Другое дело - в какой СС вы хотите эти числа выводить на экран/в файл, в общем - преобразовывать в человеко-читаемую строку. Поэтому в целом вопрос сводится к чтению справки по аргументам printf или по директивам потоков C++.
    Ответ написан
    Комментировать
  • C++11, C++14. Использование auto - признак дурного тона?

    Nipheris
    @Nipheris Куратор тега C++
    Такие дельные советы тут...

    А правило проще некуда: если вы без указания типа и так УЖЕ ИМЕЕТЕ достаточно информации, чтобы уверенно работать со значением - тогда можно использовать auto. Если чувствуете, что не имеете, или сомневаетесь, что имеете - лучше тип указать. Пример, где использование auto отлично подходит - итераторы:
    std::list<int> items;
    auto i = items.cbegin();

    Во второй строке четко написано - items.cbegin - константный итератор по items, бегущий с начала списка. Мне этого более чем достаточно. Указание типа std::list<int>::const_iterator мне никакой новой информации не принесет. Тем более, т.к. итераторы от разных контейнеров несовместимы, то мне нужно еще и сразу знать, по какому конкретно списку у меня итератор - я опять-таки посмотрю на items.cbegin, а не на тип.

    А вот auto в объявлениях функций/методов и правда ни к чему. Его, кстати, даже не сразу там разрешили использовать (только в C++14). Причина тому вновь читабельность - чтобы понять, что возращает функция, нужно прочесть ее текст как минимум до первого return, а лучше - полностью. Единственный сценарий, где без auto не обойтись при указании возвращаемого типа - это стрелочная нотация с decltype, но я думаю вы не скоро с ней столкнетесь.
    Ответ написан
    Комментировать
  • Как правильно сформировать экономный пакет данных об игроках?

    Nipheris
    @Nipheris Куратор тега C++
    Ваша проблема решается даже не просто, а элементарно.
    Для этого нужно запомнить простейший способ передачи групп элементов переменной (т.е. заранее неизвестной) длины: сначала передавать длину, а потом уже сами элементы в нужном количестве.
    Этот подход используется повсеместно. Например, когда на диск сохраняют строки переменного размера, и в строке неудобно/невозможно применить символ-терминатор, то сначала записывают длину строки (неотрицательное число нужной разрядности - байт, 2-х байтовое целое, 4-х байтовое целое), а потом уже содержимое строки. Кстати, такие строки называются паскалевскими (в альтернативу нуль-терминированным Cи-строкам).
    Разумеется, приемник пакета должнен быть достаточно умным, чтобы сначала принять длину, выделить себе некую стркутуру нужного размера (вектор подходит отлично, т.к. можно попросить его сразу зарезервировать нужное количетсво элементов), а затем записать ожидамое количество элементов.

    Вариант кода передачи:
    std::vector<PacketMultiPlayer> serverMuPackets;
    ......
    const unsigned int packetsCount = serverMuPackets.size();
    send(sock,(char*)(&packetsCount), sizeof(packetsCount), 0);
    send(sock,(char*)serverMuPackets.data(), sizeof(PacketMultiPlayer) * packetsCount, 0); // Имеем право так делать, т.к. вектор гарантирует последовательное хранение элементов. Со списком подобное делать нельзя
    Ответ написан
    Комментировать
  • Можно ли перейти от реализации для win(opengl,height map)?

    Nipheris
    @Nipheris Куратор тега C++
    0) закапываем GLUT, берем GLFW (www.glfw.org ); если это неприемлемо, отпишитесь в комментариях, сделаем другую инструкцию;
    1) берем пример, делаем окно по примеру: www.glfw.org/documentation.html
    2) когда убедились, что окно появляется и все работает, начинаем перетягивать код из урока;
    3) вызов кода отрисовки (который DrawGLScene) вставляем вместо /* Render here */;
    4) объявления виндовых дескрипторов убираем (HDC, HWND и прочие); windows.h тоже вроде не нужен;
    5) для обработки событий клавиатуры читаем вот это: www.glfw.org/docs/latest/input.html#input_keyboard , для мыши вот это: www.glfw.org/docs/latest/input.html#input_mouse . По сути все элементарно: устанавливаются колбэки, в которых уже находится код обработки;
    6) для того, чтобы адекватно выйти из главного цикла приложения (это тот, который while (!glfwWindowShouldClose(window))) в нужном месте (например, по нажатию ESC) вызываем glfwSetWindowShouldClose.

    Итого WindowProc вам уже не нужна, из WinMain возможно понадобится код инициализации и код обработки клавиатуры нужно будет вынести в колбэк.
    Вопросы в комментарии, все сразу не расскажешь.

    P.S. Вообще поищите современные туториалы, это OpenGL 2.0, этот API уже никому не нужен, в 3-м OpenGL всю архитектуру перекроили (зачем? Например затем, что вызывать glVertex для каждой вершины - это слишком затратно). Старые уроки вам будут полезны только для общего развития в CG.
    Ответ написан
    2 комментария
  • Qt progressBar, управление из своего класса?

    Nipheris
    @Nipheris Куратор тега C++
    Вариант 1:
    1) делаете в классе формы публичный метод вроде setTransferProgress(int), чтобы его можно было вызывать извне;
    2) дергаете метод формы, устанавливая нужное значение прогресса;
    3) реализуете метод setTransferProgress, чтобы он изменял состояние контролов так, как вам нужно;

    Вариант 2:
    1) делаете ваш "обычный" C++ класс QObject-классом, делаете у него слот transferProgressChanged(int);
    2) передаете объект вашего "передатчика данных" форме, и connect-ите слот transferProgressChanged к приватному методу, например updateProgress;
    3) в updateProgress обновляем контролы формы;
    Ответ написан
    2 комментария
  • Азы OpenCL( C++, Qt 5). Как собрать простейшую программу?

    Nipheris
    @Nipheris Куратор тега C++
    limon_spb пожалуй не все так просто с OpenCL.DLL и видимо ее все-таки не нужно распространять со своим приложением. Однако, как и было сказано ранее, ее интерфейс универсален и ваше приложение не придется перекомпилить под каждое устройство. Вопрос только в том, кто ее должен поставлять.

    Вот на форуме Кроноса: https://forums.khronos.org/showthread.php/6299-Ope... господин pcchen утверждает, что OpenCL.dll и ICD-либа должны устанавливаться при установке драйверов на видяху. Видимо все-таки не должны вы класть OpenCL.dll со своей программой.

    Тогда мы возвращаемся к вопросу, почему программа не запустилась у вас на машине. Случайно наткнулся на ваш вопрос 1-в-1 на SO: stackoverflow.com/questions/22098210/deploying-ope... . Я думаю у вас была та же проблема - DLL в системных папках реализует API версии 1.1, а вы разрабатываете под API версии 1.2 (что определяется теми хедерами, которые вы подключили в проект). Поэтому правильно все-таки сначала решить проблему конкретно на вашей машине. Возможно, стоит обновить драйвера, и они обновят системные библиотеки.

    В той теме на форуме так и не пришли к единому мнению относительно того, откуда должна браться OpenCL.dll. Я склоняюсь к тому, что ставить ее должны драйвера. Кстати, Dithermaster в ответах на SO говорит то же самое. Погуглите еще "deploying opencl application".
    Вот еще одна тема с обсуждением (также не советуют деплоить OpenCL.dll самому): https://forums.khronos.org/showthread.php/11392-Ye...
    Ответ написан
    2 комментария
  • Как организовать работу структуры b-дерева, файла данных и файла индексов?

    Nipheris
    @Nipheris Куратор тега C++
    Там есть поиск, вставка и удаление.
    Теперь нужно организовать работу с файлами. Файлом индексов и файлом данных.

    1) заменяете указатели на потомков в узлах дерева на абстрактные указатели или номера. Это нужно потому, что узлы дерева теперь могут быть как в основной памяти, так и на диске, поэтому при обращении к любому из узлов нужно сначала смотреть, загружен он или нет, и при необходимость загружать с диска (т.е. огранизовать простейший кэш);
    2) в листовых узлах вы будете хранить такие же абстрактные указатели, только не на узлы дерева (которые в индексном файле), а на реальные записи (которые в файле данных). С записями можно поступать точно также - проверять, загружены они в кэш или нет, при необходимость загружать и отдавать пользователю.
    3) операции изменения теперь должны научиться помечать узлы как "грязные", т.е. требующие сохранения на диск. В процессе модификации B-дерева вы помечаете как грязные все изменившиеся узлы, и потом сохраняете их диск (по окончании операции или через равные промежутки времени), после сохранения каждого узла сбрасываете флаг.

    Собственно основные изменения: организация кэша для записей данных и индекса и переделка дерева на работу с узлами через кэш, а не напрямую по указателю на BTreeNode.
    Ответ написан
    Комментировать
  • Какая разница между interface в С# и чисто виртуальными функциями в класах С++?

    Nipheris
    @Nipheris Куратор тега C++
    Одно и то же, чисто абстрактные классы в C++ это способ получить функциональность, аналогичную понятию "интерфейс" в тех языках, где оно есть (C#, Java, etc.).
    Благодаря множественному наследованию в C++ среди базовых классов могут быть как классы с реальным поведением (т.е. с реализациями каких-либо методов), так и классы-"интерфейсы", т.е. классы только с pure-virtual функциями-членами.
    Ответ написан
    Комментировать
  • Как передать char указатель функции dll, чтобы можно было в дальнейшем разобрать на массив?

    Nipheris
    @Nipheris Куратор тега C++
    [DllImport("вашалиба.dll", CharSet = Ansi, CallingConvention = CallingConvention.Cdecl)]
    public void LaunchJavaApplet([In] string[] JVMOptions);
    Ответ написан
  • Как из файла json ввести данные в таблицу QTableView?

    Nipheris
    @Nipheris Куратор тега C++
    1) создать подходящую модель (например, наследоваться от QAbstractTableModel);
    2) загрузить данные из json;
    3) реализовать модель из п.1 так, чтобы она возращала значение конкретного свойства в зависимости от запрошенного столбца;
    Ответ написан
    Комментировать