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

    @dima20155
    you don't choose c++. It chooses you
    Гуглите "Programming language roadmap" и вперед.
    Любите книги - аналогично есть много книг как по самому С++ (как от создателя языка, так и от признаных экспертов). Также легко найти множество книг и по фреймворкам/библиотекам на любой вкус, важно лишь понять что нравится (web/графика/сеть, а может что-то ещё)
    https://salmer.github.io/CppDeveloperRoadmap/
    https://roadmap.sh/cpp

    Ну и по классике, если хотите научиться разговаривать на английском - говорите. Хотите научиться разрабатывать ПО на целевом языке - разрабатывайте pet (а может и opensource?) проекты.
    Как пример
    А вот ещё
    Ответ написан
    2 комментария
  • Как в ировом движке на C++ распаралерить функции Update и Render?

    @dima20155
    you don't choose c++. It chooses you
    Это классическая задача читателей-писателей, способы решения этой задачи легко гугляся. Если вы хотите сделать функцию update потокобезопастной, то можете использовать любые доступные методы синхронизации. В данном случае нет серебряной пули и необходимо выбирать способ синхронизации самому. Вот пара простейших идей:

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

    Также интересно имеет ли смысл просчитывать физику объектов без ее отрисовки? Если данные физики качающего маятника используются лишь для отрисовки его на экране, то смысла в распараллеливании, насколько я понимаю, не очень уж много.
    Ответ написан
    1 комментарий
  • Почему русские буквы не выводятся в C++?

    @dima20155
    you don't choose c++. It chooses you
    Потому что кириллица кодируется минимум 2 байтами.
    Вам нужна длинная строка, которая основана на wchar.

    https://stackoverflow.com/questions/402283/stdwstr...
    Ответ написан
    Комментировать
  • Как писать на c++ в годот?

    @dima20155
    you don't choose c++. It chooses you
    C++ не основной язык для Godot, но есть вот такое расширение, чтобы писать на С++.
    https://docs.godotengine.org/en/stable/tutorials/s...
    Выберите правильную версию godot и следуйте инструкции. Она оочень подробная + есть несколько видео на известной площадке, где также рассказывают как использовать С++.
    Ответ написан
    3 комментария
  • Правильно ли реализовано делигирование конструктора?

    @dima20155
    you don't choose c++. It chooses you
    Если вы хотите, чтобы color и isVertical имели определенные значения - инициализируйте. Компиляторы не гарантируют, что инициализируют целочисленные значения именно нулями (хотя такое часто встречается). По некоторым style гайдам считается плохой практикой объявлять переменные без присвоения им какого-либо значения.
    Ответ написан
    Комментировать
  • Правильно ли я понимаю правила arithmetic conversions?

    @dima20155
    you don't choose c++. It chooses you
    Да, тип будет именно таким.
    Чтобы самостоятельно увидеть вывод типа, который вывел компилятор Scott Meyers предлагает намеренно создать ошибку конвертации типа и посмотреть что же компилятор написал.
    https://godbolt.org/z/6bobqTG58
    Ответ написан
    1 комментарий
  • C++ qt, как исправить no declaration matches '...'?

    @dima20155
    you don't choose c++. It chooses you
    Ошибка означает, что в заголовочном файле у вас нет объявления метода void on_Dds_button_clicked() класса MainWindow.
    Наверное, у вас есть объявление только void on_Ds_button_clicked().
    Вот похожий вопрос на stackoverflow.

    P.S. Не испытывайте судьбу - не пиши длинные названия функций, которые отличаются только 1 буквой.
    Ответ написан
    Комментировать
  • Как исправить ошибку в программе на С++, чтобы не вызывалось необработанное исключение или кнопка останова?

    @dima20155
    you don't choose c++. It chooses you
    Вообще вы написали лишь часть вопроса. А как ругается? Если ругается компилятор, то это никак не необработанное исключение, которые вылетает в рантайме. Напишите как ругается компилятор, какое у вас исключение.
    1. Ошибка компилятора.
    Возможно, компилятор ругается (особенно, если включен флаг -Werror) на бессмысленность данного if потому что оно всегда ложно.

    Я бы заменил код вывода в поток чем-то таким. Текста чуть больше, зато никаких if внутри цикла:
    std::ostream& operator<<(std::ostream& os, const Vector& vec) {
        os << "(";
        if (vec.size) {
            for (int i = 0; i < vec.size - 1; i++) {
                os << vec.coord[i];
            }
            os << vec.coord[vec.size - 1]; // последний элемент
        } else {
           os << "Unfortunately I'm an empty vector";
        }
        os << ")";
        return os;
    }

    2. На счет исключений:
    Исключения нужно ловить и обрабатывать или не допускать (зависит от архитектуры). Необработанное исключение говорит о том, что ваша программа работает не отрабатывает корректно во всех возможных ситуациях, поскольку зачастую никто не хочет, чтобы программа завершалась ошибкой внезапно, в худшем случае вы должны хотя бы оповестить пользователя о том что произошло. Самый простой способ получить исключение - поделить на 0 число с фиксированной точностью.
    Ответ написан
    Комментировать
  • Как правильно округлять числа меньше нуля?

    @dima20155
    you don't choose c++. It chooses you
    Ответ написан
    Комментировать
  • Как исправить ошибку Error LNK2019 unresolved external symbol... при вызове функции из сторонней библиотеки?

    @dima20155
    you don't choose c++. It chooses you
    У вас ошибка связана и с header файлом. Добавьте и его сюда.
    Пока вы его код, полагаю у вас проблема с линковкой библиотечных файлов.
    Ответ написан
    Комментировать
  • Защита переменных?

    @dima20155
    you don't choose c++. It chooses you
    На английском эти ключевые слова (public, private, protected) называются Access specifiers.
    https://en.cppreference.com/w/cpp/language/access
    Думаю, становится очевидным для чего они из названия.

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

    Например, вы можете хранить не сами значения, а их хеш или, например, хранить их с определенным смещением (скажем, денег у вас в игре 100, а в переменной у вас хранится на 5x + 7 денег больше, просто чтобы запутать тех, кто захочет вас взломать). Можете также преобразовать число в строку и как-то хитро изменить (например реверсировать). Все эти способы несколько усложнят прямое чтение переменной из памяти, основываясь лишь на значении в GUI. Но вот ничто не мешает реверс-инженеру пойти и посмотреть что у вас сейчас на вершине стека сейчас у вашего процесса и таким образом понять где искать саму переменную, которая хранит количество денег в игре. Это, конечно же, в разы сложнее и снизит количество людей, которые смогу "взломать" вашу программу с помощью ArtMoney.

    Чтобы ещё сильнее усложнить жизнь взломщикам можно вовсе вынести значение переменной из памяти (то есть копия значения у вас в памяти все ещё есть, но вот увеличение/уменьшение значения переменной происходит через посредника, например, сервер, базу данных, файл, subprocess. Возможно, прожженные игроделы подскажут и более простые/интересные способы.
    Ответ написан
    Комментировать
  • Почему не работает метод clone для класса Test1?

    @dima20155
    you don't choose c++. It chooses you
    В почему это
    Test1 asd = v[1]->clone();
    Должно работать?
    В лучшем случае можно заставить работать такой код.
    Test asd = *v[1]->clone();

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

    Не очень понимаю зачем вам в принципе этот метод клон нужен, чем вас не устроил копирующий конструктор?
    Ответ написан
    Комментировать
  • List убирает string значения из класса, что делать?

    @dima20155
    you don't choose c++. It chooses you
    Во-первых, зачем вы приводите целый исходник сюда. Люди куда быстрее поймут суть, если вы сократите иерархию классов до демонстративного минимума.

    Во-вторых, во всех ваших case'ах
    Создается временный объект, затем вы зачем-то создаете ещё и временную переменную-указатель и сохраняете его адрес (зачем?). А после запихиваете все это в лист. Объект создается на стеке и при выходе за границы фигурных скобок вызывается деструктор и он перестает существовать, а все его содержимое будет перезаписано любой следующей переменной, размешенной на стеке. Вот код, о котором я говорю:
    case 1: {
          cout << endl << "Введите модель:";
          cin >> model;
          cout << endl << "Введите прозводителя:";
          cin >> producer;
          cout << endl << "Введите цену:";
          cin >> price;
          cout << endl << "Введите год выхода:";
          cin >> year;
          Appliances appliances{ model,producer,price,year };
          Appliances* pb = &appliances;
          catalog.push_back(pb);
          break;
        }


    Вот наглядный пример того что у вас получается.
    https://godbolt.org/z/bx5Wbo1bG

    Как исправить? Создавайте элемент в куче (new OhMyClass()). А лучше храните в std::list, например, std::unque_ptr
    Ответ написан
    2 комментария
  • Как создать шаблон структуры, которая будет принимать базовые типы данных и класс vector?

    @dima20155
    you don't choose c++. It chooses you
    Можно использовать перегрузку оператора <<
    Можно использовать новомодный std::input_or_output_iterator или if constexpr
    или вовсе явно специализировать/перегрузить шаблон для нужного вам типа.

    Вот один из простейших вариантов. Просто добавьте перед функцией main.
    template <typename T>
    std::ostream& operator<<(std::ostream &os, const S<T>& s)
    {
        if constexpr (std::ranges::range<T>) {
            const auto& val = s.GetVal();
            for (const auto& i : s.GetVal()) {
                os << i << " ";
            }
        } else {
            os << s.GetVal();
        }
        return os;
    }


    Все ещё не универсально, поскольку работает не со всеми контейнерами, а только с теми, которые хранят значения и могут в range_base loop

    В таком случае вам больше не нужны функции (если они использовались лишь для вывода информации в консоль)

    PrintVal
    PrintVector
    GetVector

    Можно даже избавиться от GetVal, если вам не нужен этот геттер в остальном коде, тогда нужно просто подружить функцию с классом.
    Ответ написан
    4 комментария
  • Как получить адрес памяти переменной в массиве, а не адрес индекса массива?

    @dima20155
    you don't choose c++. It chooses you
    Вопрос а что такое Figure?
    Указатель на базовый класс? тогда у вас в массиве уже лежат указатели, посмотрите их значения.
    Массив ссылок запрещен.
    Массив объектов типа MyClass? Как и простой массив int они лежат последовательно в памяти, т.е. их адресс это адресс 0 элемента массива соответствующим с смещением.
    Ответ написан
    Комментировать
  • Как сделать динамическую подгрузку кода?

    @dima20155
    you don't choose c++. It chooses you
    Мне кажется, вам лучше сформулировать более конкретно ваши задачи, возможно, уже есть готовое решение для вас.
    Помимо перечисленного выше, есть интерпретаторы языка С++ (которые, конечно, так себе, но попробовать их можно), а возможно, вам для вашей цели может быть полезным grpc.
    Ответ написан
    2 комментария
  • Как работать с большими числами в C++?

    @dima20155
    you don't choose c++. It chooses you
    https://faheel.github.io/BigInt/
    https://github.com/Mariotti94/BigFloat
    и аналогичные либы.
    Для не слишком больших есть Quadruple(128) и Octuple(256) типы.
    https://en.wikipedia.org/wiki/Quadruple-precision_...
    Внутри, естественно, массивы.

    Думаю, проще брать сразу BigFloat и не мучаться с 128/256 битными float'ами
    Ответ написан
    Комментировать
  • Как передать двойной массив в подкласс из класса, сохранив адреса массива?

    @dima20155
    you don't choose c++. It chooses you
    У вас разные типы
    this->figure = figure[4][4]; // ТУТ КРИЧИТ СРЕДА

    this->firgure - bool [4][4]
    аргумент конструктора - bool * [4][4]

    UPD:
    Забыл упомянуть про хороший читаемый вариант с ссылкой.
    https://godbolt.org/z/W87Y8xWh3

    И про не такой хороший с помощью указателя, который опаснее:
    https://godbolt.org/z/c4Gsb8Mz5

    И конечно же лучший вариант std::array и ссылка внутри класс Rotation на std::array
    Ответ написан
    2 комментария
  • Как лучше организовать архитектуру классов?

    @dima20155
    you don't choose c++. It chooses you
    Указатель/ссылка это вполне ок использовать, но зачастую лучше реализовать взаимодействие через класс-интерфейс.
    Например, вы можете захотеть использовать разную реализацию для однопоточности и многопоточности. В таком случае крайне удобно будет иметь интерфейс. Возвращаясь к ссылке/указателю на класс: это может быть тоже приемлемо, но нужно понимать что вы будете делать с Storage, кто будет им владеть и т.д.

    Также можно реализовать взаимодействие через callback функции (что по сути упрощённый вариант интерфейсного класса).
    Ответ написан
    Комментировать
  • Как работает заполнение одномерного массива по типу двумерного, если данные по идеи никак не меняются(добавляются или изменяются)?

    @dima20155
    you don't choose c++. It chooses you
    Вам стоит почитать об указателях.
    Размер массива очень даже важен.
    Вы создаёте массив, а затем пишите данные по указателю на массив с некоторым смещением. Фактически ничто не мешает вам писать что угодно и куда удобно (в пределах памяти, доступной вашей программе) и ничего вам за это не будет. В данном случае вы нагло пишите данные по указателю (который указывает на данные в области .data). данная область памяти значительно больше 1 байта и все, что вы туда записали будет храниться в ней. Проблема заключается в том, что массив имеет длину лишь 1 байт, а значит вы пишите в память, которая не принадлежит данной переменной/массиву, а принадлежит какой-то другой переменной и тем самым изменяете значение этой переменной.

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

    Также можете попробовать создать массив в динамической памяти размером 1 байт, а потом заполнить своим кодом двумерный массив размера так 100х100 и получить классический SEGFAULT от операционной системы.

    К сожалению, уместить в 1 байт целый массив нельзя, а может оно и к лучшему.
    Ответ написан