Задать вопрос
  • Какой наиболее удобный (автоматизированный, простой) способ работы с двумерными динамическими массивами (матрицами) в С++?

    @D3Nd3R
    Есть решение из замечательной библиотеки dlib dlib.net/linear_algebra.html
    Заголовочный файл #include < dlib/matrix.h >, на сайте есть много примеров.
    Ответ написан
    Комментировать
  • Как логировать в БД запрос/ответ вебсервиса (в частности jax-ws на tomcat/glassfish)?

    @bromzh
    Drugs-driven development
    Томкат не поддерживает всё из JavaEE, это лишь контейнер сервлетов, а не полноценный ApplicationServer. Так что либо используй TomcatEE, либо другие сервера (я рекомендую WildFly).

    Про запись лога в БД можно почитать тут.
    Ещё можно использовать interceptors (перехватчики). Это часть JavaEE, перехватывать можно методы бинов. Подробнее тут и в гугле.

    В томкате нет БД, там вообще всё по минимуму. Чтобы подключить БД надо самому добавлять jar-файлы с реализацией JPA, самому настраивать базу в приложении. При этом, JTA и другие штуки будет сложно подключить и настроить, потому что томкат не ApplictionServer. Лучше взять WildFly. Там уже есть один DataSource по-умолчанию (БД в оперативной памяти, очищается после перезапуска сервака), и легко подключить новый источник к самому веб-серверу.
    Ответ написан
    1 комментарий
  • Как в конструкторе скопировать все данные в создаваемый объект из объекта того же типа, получаемого из функции в этом конструкторе?

    @Alexander1705
    То, что вы написали, называется делегирующий конструктор. И это работает начиная со стандарта C++11.
    Ответ написан
    Комментировать
  • Как реализуется двухканальный режим работы памяти в контроллере памяти (архитектурно/логически/схемотехнически)?

    hahenty
    @hahenty
    ('•')
    2-х канальный режим это и есть одновременный опрос в 2 места.

    В самом идеальном случае скорость доступа максимальна, когда запрос идет в разные физические планки, тут понятно, что каждая планка со своим контроллером занята только своими данными.

    Но часто случается так, что запрос идет в одну планку, тогда придется ждать — так одноканально.

    Для решения этой оказии существует алгоритм доступа, когда адреса и операции от процессора суются в буфер, а оттуда контроллер памяти делит адреса по планкам, если может.

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

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

    Так мне думается.
    Ответ написан
    Комментировать
  • Что использовать в С++(Qt,Boost) для простого серверного приложения-хранилища данных?

    Nipheris
    @Nipheris Куратор тега C++
    cpp-netlib.org или doc.qt.io/qt-5/qnetworkrequest.html если нужен HTTP
    Boost::Asio, если не нужно HTTP
    Berkeley Sockets все еще в моде, если не боитесь C-style
    На последние два можно накрутить Protocol Buffers через stream-ы, если протокол достаточно сложный или предполагает расширение.
    Ответ написан
    Комментировать
  • Как правильно составить функцию qHash для объекта содержащего два QString? Или просто какой алгоритм для хеширования двух строк?

    PavelK
    @PavelK
    У себя сделал так же как и у вас.
    склеивание, а между ними разделитель. работает достаточно быстро.
    Ответ написан
    Комментировать
  • Как правильно составить функцию qHash для объекта содержащего два QString? Или просто какой алгоритм для хеширования двух строк?

    Nipheris
    @Nipheris Куратор тега C++
    А почему такая странная потребность в УНИКАЛЬНОМ хэше (который вы кстати в принципе не получите для двух строк по 20 символов, т.к. хэш-значение - типа uint)?
    > это РАЗНЫЕ объекты, несмотря на то что конкатенация firstName + lastName равна.
    ну и пусть, совпадет один раз, не такой уж частый кейс для имени и фамилии. У вас таких Каримов с одинаковым конкатенированным именем тысяча штук будет?
    Ответ написан
    4 комментария
  • Для чего нужна передача объекта в функцию по значению и по указателю в С++?

    @Alexander1705
    Указатели действительно не очень востребованы в языке C++, так как в большинстве случаев лучше использовать ссылки. Однако в языке С ссылок нет, и поэтому для совместимости иногда используют указатели.
    Передача по значению создаёт копию передаваемого объекта. Это используется тогда, когда в функции (или методе) вам может понадобится изменить объект, однако эти изменения не должны затронуть тот объект, который вы передавали.

    Например, поиск наибольшего общего делителя:
    int gcd(int a, int b) {
       int c;
       while (b) {
          c = a % b;
          a = b;
          b = c;
       }
       return abs(a);
     }

    В функции изменяются копии переданных объектов, а не сами объекты.
    int a = 16;
    int b = 4;
    gcd(a, b);
    cout << a << ' ' << b; // Выведет "16 4", а не "4 0"


    Upd.1
    Указатели используются в многих структурах данных. Например, связный список:
    template<T> struct LinkedListItem
    {
        T value;
        LinkedListItem* next;
    };

    Значение здесь использовать нельзя, так как объект не может содержать внутри объект того же типа (получается бесконечная рекурсия). Ссылку использовать также нельзя, так как ссылка должна быть сразу привязана к объекту (переменной), а в случае со списком, элементы могут быть добавлены/изменены в любое время.

    Upd.2
    Можно создавать указатели на функции. Функцию нельзя передать по значению или по ссылке.
    #include <iostream>
    
    float f1(float x)
    {
        return 2 * x + 6;
    }
    
    float f2(float x)
    {
        return -3 * x * x + 8 * x - 6;
    }
    
    void printTable(float(*f)(float), float beg=0.f, float end=10.f, float step = 1.f)
    {
        for(float x = beg; x <= end; x += step)
        {
            std::cout << "x = " << x << "\ty = " << f(x) << '\n';
        }
    }
    
    int main(int argc, char** argv)
    {
        printTable(f1);
        printTable(f2);
    }
    Ответ написан
    2 комментария
  • Для чего нужна передача объекта в функцию по значению и по указателю в С++?

    Nipheris
    @Nipheris Куратор тега C++
    Как передавать - по значению или по указателю - целиком зависит от природы объекта (ссылки - отдельная история, отвечу ниже).
    Существует две важнейших категории обрабатываемых в программе данных, которые редко рассматриваются в явном виде, но от которых, как говорится, не убежишь, по кр. мере в нефункциональном языке.
    Первая категория - это "значения". Я не готов вам дать сейчас точное определение, но можете представлять себе эту категорию как те значения, что вы знаете из математики. Особенностью этих "значений" является то, что они несут ровно столько информации, сколько в них самих есть (в их представлении в ЭВМ). Ну то есть если вы видите строку "Василий", и другую строку "Василий" в другом месте, то как "значения" они ничем не отличаются. Также, одно целочисленное значение 5 ничем не отличается от другого 5. Кроме того, у значения нет жизненного цикла - у него нет прошлого и будущего, оно есть такое, каким оно было создано. Иными словами, у значения нет понятия изменяемости, оно не привязывается ко времени. Значение 6 - это уже другое значение, и неважно, как оно было получено. Важно, что значения не обязательно должны быть примитивными: комплексное число (5, 7) это такое же значение, как и его составляющие 5 и 7.
    Вторая категория - это "переменные". Это уже совсем другие сущности в программе. Это такие контейнеры, куда кладутся значения, причем под "кладутся" понимается хорошо знакомая вам операция присвоения. Важно, что несмотря на то, что переменная как контейнер может содержать различные значения в разные промежутки времени, у нее всегда есть некоторый неизменный идентификатор. В языках с прямым доступом к памяти, таких как C++, это указатель. Неважно, где находится ваша переменная - на стеке или в куче - важно, что это контейнер, и у него есть уникальный идентификатор. Т.к. содержимое контейнера может изменяться - то мы можем говорить о прошлом и будущем этого контейнера, зная его идентификатор.
    Если сузить понятие объекта до такой сущности, которая может изменять свое состояние, то объект в проекции на язык C++ - ничто иное, как переменная с четко определенным интерфейсом изменения состояния. Отсюда вытекает, что в плюсах identity объекта - это есть указатель на участок памяти, где этот объект находится.
    Когда вы сравниваете значения, вы должны сравнивать их "начинку". Понятно, что ваши значения технически лежат в каких-то переменных, но 5 и 5 будут равны вне зависимости от того, где каждая из них находятся.
    Другое дело объекты. Их природа такова, что один Студент не эквивалентен другому Студенту, если их identity, т.е. указатели, различаются (соотв-но, если указатели совпадают, то это, безусловно, один и тот же Студент). Это в общем-то очень хорошо моделирует реальный мир: даже если у студентов совпадают ФИО и дата рождения (и вообще все данные, что мы о них имеем) это не значит, что это один и тот же человек.
    Когда вы плотнее займетесь ООП в C++ вы поймете, что именно адрес объекта в памяти - первичная информация для начала манипуляций с объектом. Адрес можно передать не только указателем, но и ссылкой, однако именно указатели, например, удобно сравнивать друг с другом. Список из студентов - это std::list<Student*>, а не std::list<Student>. Безусловно, вам никто не мешает использовать второй вариант, но тогда ваши студенты будут значениями (!), а не объектами (кстати, именно во втором случае std::list потребует от вас оператора сравнения для студентов).
    Т.к. в С++ все значения копируются по умолчанию (перемещение сейчас не рассматриваем), то для моделирования "объектов", как самостоятельных сущностей с собственным жизненным циклом, нам нужны указатели и ручное управление памятью.
    Ссылки - это лишь обертка, которая превращает указатель либо в l-value, либо в r-value, в зависимости от ее типа. const string& - это экономный способ смоделировать передачу "значения", а Student& - это по сути то же самое, что и Student*.
    Ответ большой и сумбурный, но вам нужно еще со многим разобраться. Если что не понятно - спрашивайте в комментах.
    Ответ написан
    3 комментария
  • Как и где можно искать различные open source проекты (желательно русскоязычные)?

    Если ты ещё конкретно не знаешь чего хочешь, то посмотри на SourceForge - одна из крупнейших площадок для открытых проектов. Там есть удобный каталогизатор по языкам программирования, по целевым операционным системам, по стадиям развития проектов и др.
    Ответ написан
    1 комментарий
  • Как восстановить знания по C++ на сегодняшний день?

    @Koss1024
    0. Прочитайте Страуструпа последнее издание (англ). Если язык вы знали то это лучшая книга чтобы обновить знания

    1. C++11 C++14, в производстве чаще пока еще С++03
    2. Лучший компилятор clang++ (поддерживает любой стандарт и любую платформу)
    3. boost это набор библиотек на все случаи жизни самый хорошо сынжинереный. Стоит писать не под него а с использованием
    4. пункт 3
    5. C++ для задач требующих точного понимания стоимости каждой операции, это embedded DSP Server computing
    Math много чего еще

    Учтите, С++ это инструмент который нужно учить постоянно

    Дополню
    -----------
    С++ мультипарадигменный
    А так же много уровней абстракции поддерживает

    На нем можно писать как на чистом С - это самый низкий уровень
    Можно ООП и абстракции
    Можно паттерны
    А можно функциональный стиль

    С С++ в этом и проблема что знать нужно очень много.

    Я могу сказать что я читал на протяжении своей карьеры
    Прежде всего я умел программировать и имел представление об алгоритмах и модели памяти
    (что такое указатели, алокация удаление и т д)

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

    Потом Страуструп (тогда это было издание по стандарту 03). Здесь я дополнил свои знания деталями которые пропустил при самостоятельном изучении. Тут стоит отметить что Страуструп весьма странная книга и написана тяжело. Секцию же ООП вообще там лучше не читать (самая последняя).

    Где-то рядом я прочитал Гради Буч - ООА и ООП с примерами применения. Очень хорошая кика чтобы понять к чему все это придумали вообще. Сильно выправляла мозги

    Потом был Керниган и Ричи Язык программирования С. Эту я прочитал просто от безделья, но теперь считаю что это было необходимо. Здесь можно понять зачем придумали именно С. И насколько там все просто, задумано.

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

    С Мейерс - Эффективное использование С++ туда же. Прекрасный разбор.

    Макконнел - Совершенный код. Очень крутая книга. Она отшлифует уже почти бриллиант.

    Помимо всего прочего я работал над проектами и постоянно читал всяческие форумы, блоги, дискутировал с коллегами. Решал задачки разных собеседований.

    Отдельного внимания заслуживает книга Банды четырех (Паттерны).
    Я ее с трудом дочитал, читал ее я уже аж после всего перечисленного и после примерно 7-8 лет опыта С++.
    Я уже давно был Senior dev. и наконец нашел таки время и для нее. Она мне показалась до ужаса скучной и очевидной, поскольку почти все предложенные решения я придумывал и сам неоднократно. Кроме того, большинство этих решений неоправданно тяжелы, и очень запутывают код. Тема холиварная и спать надо много, но я пожалуй остановлюсь только на том что в моей практике, худшими с точки зрения цены ошибок были разработчики которые учились начиная с этой книги. Их код недодерживаем запутан и очень плохо поддается рефакторингу. Такой код имеет самые долго отлеживаемые ошибки.

    Где-то рядом я прочитал Фаулера - Рефакторинг. Вполне себе неплохо. Рекомендую. Но тут стоит к опытному коллеге обратиться. Идея то проста Тесты - Маленькие комиты - YAGNI KISS и SRP но детали лучше познавать на практике.
    У меня был хороший лид, который меня в конце концов научил :)

    Совсем забыл! Александреску же! Скажем так - не так страшен Александреску как тот кто его начитался :)
    Фана доставил много, а так же дал возможность на эти игрища потерять около 3-х месяцев работы. Даже не знаю
    стоит ли читать. Наверное стоит, но нужно помнить что на практике лучше не использовать если вы уже не эксперт.

    Остальное С++ не касается, но чтобы стать профессионалом Вам потребуются алгоритмы и структуры данных (Кормен, Кнут), многопоточность (Энтони Уильямс), другие языки(питон, JS, java), оптимизация и профилирование.
    и много много разных специфических знаний

    Удачи Вам в этом нелегком но, безусловно, интереснейшем пути :)
    Ответ написан
    7 комментариев