Задать вопрос
Ответы пользователя по тегу C++
  • Есть ли способ получать предупреждение при преобразовании char в int?

    @res2001
    Developer, ex-admin
    По стандарту sizeof(char) == 1, sizeof(int) >= 2.
    char->int и int->char - это 2 разных преобразования. Судя по вопросу для вас это одно и то же.
    Первое проходит без предупреждения, поскольку значимость не теряется. На второе компилятор ругнется, обычно это warning, опциями компилятора можно сделать чтоб был error.
    Повышение char до int не зависимо от того какой конкретно char в данной системе вполне стандартизовано и укладывается в стандартное расширение целочисленных типов.
    Обратное преобразование приведет к обрезанию значащих бит, это то же описано в стандарте.
    Ответ написан
    2 комментария
  • Где можно почитать/посмотреть о написании dll на c++?

    @res2001
    Developer, ex-admin
    WinAPI учить не надо - бессмысленное занятие - он достаточно большой и весь он вам вообще вряд ли когда-нибудь пригодится. Но надо знать где искать по нему информацию.
    По написанию DLL на С++ ... погуглите в конце концов. Там есть свои тонкие моменты, но это не сложно.
    Вот что нагуглилось сходу:
    https://learn.microsoft.com/ru-ru/cpp/build/walkth...
    Ответ написан
    Комментировать
  • Как исправить ошибку в программе на С++, чтобы не вызывалось необработанное исключение или кнопка останова?

    @res2001
    Developer, ex-admin
    1. у вас в конструкторе выделяется динамическая память. Но деструктора у вас нет. Память не освобождается, после удаления объекта - утечка.
    2. Еще про конструктор. Внимательно посмотрите на строчку: coord = new double[size];.
    Чему равно значение переменной size в ней? Какого размера выделится буфер?
    3. Конструктор копирования реализован не правильно. Если вы создадите объект с его использованием, то он будет использовать тот же блок динамической памяти, что и исходный объект. Ни к чему хорошему это не приведет, вряд ли вы рассчитывали на такое поведение.

    На счет ошибки компилятора - хорошо бы увидеть текст ошибки. Условие в operator<< действительно всегда ложно. Надо сравнивать с vec.size - 1
    Ответ написан
    Комментировать
  • Почему tellg() неявно приводится к int при инициализации int, но не может быть сложенным с int?

    @res2001
    Developer, ex-admin
    попробуйте так: 2 + telg() На gcc вроде прокатывает без предупреждений.
    Но это опасно, т.к. tellg может вернуть ошибку (-1) и она в этом случае останется а) необработанной б) ваш код не поймет, что была ошибка - выражение вернет корректное положительное не правильное значение. Возможно именно по этому выдается предупреждение (в GCC предупреждение, а не ошибка).
    Ответ написан
    Комментировать
  • Как правильно написать функцию принимающую универсальную ссылку?

    @res2001
    Developer, ex-admin
    ifs может быть const

    Поток не может быть const. Когда вы читаете/пишете в поток у него меняются внутренние атрибуты. В const потоке вы ничего не сможете изменить, а следовательно ни писать туда ни читать из него не сможете - зачем он такой красивый нужен?
    как я понял нужно использовать и std::forward, но не понимаю куда его вписать корректно

    Если вы будете поток дальше передавать в какие-то функции, то заверните поток в forward. То же самое, если надумаете возвращать поток из функции.
    Ответ написан
  • Error LNK2019: ссылка на неразрешенный внешний символ public: void __cdecl Window::create(void)?

    @res2001
    Developer, ex-admin
    но window.cpp задумывается как часть библиотеки которую можно потом установить

    Плагин что ли?
    Ну вы и должны с библиотекой работать соответственно. Как-то проверять наличие плагина, если он есть - грузить его в память, получать адреса его экспортируемых функций, использовать экспортируемые функции через указатели на функции, а не напрямую. А так же вы должны предусмотреть штатный вариант работы, когда библиотеки нет.
    Ответ написан
    Комментировать
  • Как убедиться что атомарные операции будут выполнены точно правильно?

    @res2001
    Developer, ex-admin
    Ситуация вполне вероятна. На сколько я знаю, нет гарантии, что поток после создания сразу получит процессор для выполнения.
    Делайте проверку в get в цикле, если x.load вернул false, то можно вызвать yield(), чтоб напрасно не жрать процессор в цикле.
    Ответ написан
  • Вылетает программа на C++ с кодом -1073741571 (0xC00000FD)?

    @res2001
    Developer, ex-admin
    Если вы под виндой, то запустите программу в дебагере без точек останова. Когда произойдет ошибка, то дебагер остановится в том месте где произошла ошибка, перейдете по стеку вызовов к вашему последнему вызову (т.к. ошибка может проявляться где-то в коде стандартной библиотеке) и начнете анализировать это место программы.

    В линуксах надо включить создание coredump в ОС, выполнить программу, получить файл coredump и проанализировать его в gdb. Схема анализа кода та же, что под виндой.

    Возможно у вас выход за пределы массива. При анализе внимательно смотрите на используемые индексы и размеры выделенного вектора к которому идет обращение.

    Результаты вашего анализа можете скинуть сюда.
    Ответ написан
    Комментировать
  • Что делать с ошибкой unresolved external?

    @res2001
    Developer, ex-admin
    У вас не включен в сборку Firm.cpp. Поэтому все что в нем определено и используется в unit1.cpp будет вызывать ошибку.
    Как собираете проект?
    Ответ написан
    Комментировать
  • С++ На всех ли платформах одинаковая точность операций с float?

    @res2001
    Developer, ex-admin
    Форматы чисел с плавающей точкой стандартизованы IEEE754.
    Скорее всего, операции выполняемые процессором над числами с плавающей точкой будут давать одинаковый результат на разных платформах.
    Но вот программные реализации различных математических алгоритмов из стандартной библиотеки, типа того же sqrt и т.п., могут отличаться.
    Для гарантии, вам нужно использовать для этих целей какую-то единую библиотеку для всех платформ, а не стандартный math.h.
    Ответ написан
    1 комментарий
  • Как быстро округлить timestamp до секунд, минут, часов, дней и т.д.?

    @res2001
    Developer, ex-admin
    Думаю, для округления вплоть до дней можно просто отбрасывать остаток от деления на соответствующую константу. Константы вычислить заранее для 1 дня, 1 часа и 1 минуты.
    Округление до года и месяца - по предложенной jcmvbkbc схеме.
    Ответ написан
    Комментировать
  • Как показать все листья в бинарном дереве?

    @res2001
    Developer, ex-admin
    Листьями в дереве считаются узлы, у которых нет потомков.
    Потомки в коде задаются членами узла left и right, соответственно if(p->left == NULL && p->right == NULL), то узел - лист.
    Делаете проход по всем узлам и выводите только те узлы, где условие выполняется.
    Ответ написан
    Комментировать
  • Как думаете, с чем связана ошибка и как ее исправить?

    @res2001
    Developer, ex-admin
    Про size_t - если вы на 100% уверены, что у вас никогда не случится потеря данных при преобразовании из 8 байтного беззнакового size_t в 4 байтный знаковый int, то можете сделать явное преобразование типов (cast). Но гораздо правильней для размера (всего чего угодно) использовать size_t (а не int), как это давно уже делают в std.
    Про strncpy - в некоторых случаях она может быть не безопасной. Если вы на 100% уверены, что в вашем случае она точно безопасна, то можно забить на ошибку, объявить макрос, который указан в тексте ошибки и на этом проблема будет исчерпана. Но есть безопасные аналоги строковых функций у них к имени добавляется суффикс _s. В вашем случае безопасный аналог strncpy_s. Используйте безопасные функции. Безопасные функции немного медленней работают, за счет дополнительных проверок и т.п.
    Ответ написан
    6 комментариев
  • Можно ли создать пустую структуру, а потом её заполнить внутри функции?

    @res2001
    Developer, ex-admin
    В плюсах структуры это те же классы, но у них по умолчанию используется модификатор доступа public, а в классах private - это вся разница между ними.
    Напишите для структуры конструктор по умолчанию, в котором будете присваивать нужные значения членам структуры. После этого при объявлении любого экземпляра структуры:
    Date date;
    члены структуры будут принимать значения, заданные в конструкторе по умолчанию.
    Ответ написан
  • Почему не работает пузырьковая сортировка двумерного динамического массива?

    @res2001
    Developer, ex-admin
    1. В result в цикле сортировки вложенный цикл должен быть до y, а у тебя до х, так же как верхний цикл.
    2. Как писал mayton2019 для сортировки не хватает дополнительного цикла. Просто сделай сначала сортировку одномерного массива и поймешь зачем он. Сейчас у тебя только одна итерация сортировки для каждой колонки проходит.
    3. Посмотри внимательно сюда:
    int temp = Arr[i][j + 1];
    Arr[i][j] = Arr[i][j];
    Arr[i][j + 1] = temp;

    И пойми, что этот код ничего местами не меняет. А должен.
    Ответ написан
    2 комментария
  • Является ли такой способ выделения массива объектов на хипе идиоматичным?

    @res2001
    Developer, ex-admin
    Можно использовать std::malloc вместо new.
    Если класс полиморфный, то можно предварительно вычислять max из размеров всех детей и использовать это значение для выделения массива. Список детей должен быть заранее известен.
    Ответ написан
    1 комментарий
  • Как в деструкторе базового класса вызвать переопределённый метод?

    @res2001
    Developer, ex-admin
    Никак. Когда работает деструктор базового класса объект наследник уже не существует.
    Так что "чистите" наследник в деструкторе наследника, а базовый класс в деструкторе базового класса.
    Вот старинная статья на хабре, но, на сколько я знаю, и сейчас все работает так.
    Ответ написан
    Комментировать
  • Не получается вернуть строку. Как исправить?

    @res2001
    Developer, ex-admin
    1. Лучше бы вы использовали std::string, а не нативные ("сырые") строки.
    2. Нативные строки - это не строки в привычном для С++ смысле (и в смысле интерпретируемых ЯП). У них нет встроенных операций типа конкатенации, выделения подстрок и т.п. Все это реализуется функциями в стиле Си str*
    3. Если вы хотите вернуть сырую строку, то надо:
    3.1. Массив под строку выделять в динамической памяти (или передавать его как параметр в функцию и его заполнять). Сейчас у вас автоматический массив, а он исчезнет, как только отработает оператор return и строка по факту не вернется (хотя вернется указатель, но он будет указывать в место на стеке, в котором уже нет вашей строки).
    3.2. Возвращать char*. Сейчас тип возвращаемого значения в вашей функции char - а это один символ, а не строка.
    4. Размер строки явно будет больше, чем size байт. На сколько больше - нельзя сказать заранее. Поэтому обычно выделяют достаточно большой буфер с запасом, чтоб покрыть все возможные варианты и при добавлении в буфер очередной подстроки контролируют размер буфера - чтоб оставалось место для очередной добавляемого куска и завершающего нулевого символа. Строка может быть равна size только в случае, если все числа в массиве будут состоять из одной десятичной цифры. Да и в этом случае требуется дополнительный байт на нулевой символ. Так что минимальный размер буфера должен быть size+1, реально он должен быть еще больше.
    Ответ написан
    Комментировать
  • Как сохранить значения нескольких переменных в С++ 17?

    @res2001
    Developer, ex-admin
    Вы же из getInfo возвращаете вектор, вот и принимайте вектор. В нулевом элементе вектора будет normal_weight, в первом weight. Вместо вектора можно было бы использовать std::pair или std::tuple. Они хранят свои данные статически, а вектор выделяет динамический массив, что в вашем случае максимально избыточно.

    Другой вариант передавайте в getInfo ссылки, тогда не надо будет ничего возвращать, значения в main появятся сами собой :-) Сейчас у вас аргутменты getInfo не понятно какую роль выполняют.
    Ответ написан
  • Почему переопределение метода без virtual -- это не переопределение?

    @res2001
    Developer, ex-admin
    Переопределить можно в любом случае, хоть с virtual, хоть без.
    Но тут важно что вам надо от переопределенного метода. Если вам нужно использовать полиморфизм, то нужно ставить virttual, если нет - то нет.

    Например дополним ваш пример функцией:
    void func(struct A &a)
    {
      a.fn();
    }
    
    int main() {
      B b;
      b.fn();
      func(b);
    }

    И передадим туда ссылку на b. Будет напечатана А, т.к. методы fn не виртуальные.
    Если были бы виртуальные, то напечатается B - полиморфизм в действии.
    Ответ написан
    Комментировать