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

    @Mercury13
    Программист на «си с крестами» и не только
    Вам, как я понял, нужен standard I/O redirection — чтобы то, что мы пишем куда-то, служило входом для процесса FFMPEG, заранее запущенного. В Windows делается это через каналы (pipes) и CreateProcess.
    https://msdn.microsoft.com/en-us/library/windows/d...
    Ответ написан
    Комментировать
  • Что произойдёт после move-касте содержимого shared_ptr?

    @Mercury13
    Программист на «си с крестами» и не только
    После move-каста содержимого shared_ptr мы говорим: объект под shared_ptr идёт на заклание, и в операциях перемещения мы можем потрошить его как угодно — лишь бы объект остался корректным. В данном коде (как я уже писал, он не компилируется) у нас одни ссылки, и не будет ровным счётом ничего: не выполнится ни одна операция перемещения.

    Однако возможна такая ситуёвина, никак не связанная с временными ссылками. Во втором есть неуправляемая ссылка на первый — и при определённых условиях она может стать висячей.

    Если в T2 всё-таки не ссылка, а экземпляр (T1 m_var), возможно, операция перемещения оставляет объект под ptr в некорректном состоянии, и деструктор ~T1() не может его уничтожить, или какая-то из операций над ptr не подозревает, что объект под ptr выпотрошен.

    UPD. Что делает updateSearchResults? Только он может продлить время жизни объекта, сохранив где-то shared_ptr.

    UPD2. Константная временная ссылка (const T&&) никакого смысла не несёт (по факту в STL пару раз используется). «Неизменный» и «можно выпотрошить» — это слегка противоречивые вещи.
    И всё-таки я грешу на updateSearchResults, который сохраняет где-то объекты. Проблема может решиться, если в PoiSearchPlacesLocation ссылку заменить на shared_ptr. И — ВНИМАНИЕ — соответствующим образом подкорректировать сигнатуру конструктора. У shared_ptr есть конструктор, который берёт под управление любой объект-указатель, создавая новый счётчик, но хреново будет, если один и тот же объект управлять двумя разными счётчиками.
    Ответ написан
  • Какую библиотеку использовать для построения простых графиков?

    @Mercury13
    Программист на «си с крестами» и не только
    Если Qt — то QWT.
    Ответ написан
    1 комментарий
  • Как исправить данный алгоритм поиска максимального подмассива?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Учите, что означает операция «запятая». Если вы хотите выдать наружу три числа — так и пишите возвращаемым типом не int, а структуру из трёх чисел.
    2. Передавать vector по значению невыгодно, лучше по константной ссылке.

    struct ArrayOut {
      int low, high, sum;
    
      ArrayOut() : low(0), high(0), sum(0) {}
      ArrayOut(int aLow, int aHigh, int aSum) : low(aLow), high(aHigh), sum(aSum) {}
    };
    
    
    ArrayOut Find_Max_Crossing_Subarray(const vector<int>& A, int low, int mid, int high)  { ... }


    UPD. Операция «запятая» — это странный хак Си, позволяющий впихнуть несколько операторов туда, где разрешён только один. В основном в цикл for.
    Ответ написан
  • Java или C++ в качестве первого языка. Что выбрать?

    @Mercury13
    Программист на «си с крестами» и не только
    Только Java. Почему…
    1. Достаточно удачная стандартная библиотека.
    2. Проверка массивов на индекс — для начинающего бесценно.
    3. Не настолько полагается на указатели, когда человек ещё толком не знает, что это такое.
    4. Очень строгая проверка типов.
    5. Статическая типизация, Си-подобный синтаксис (хотя всё это у обоих).
    6. Сообщения об ошибках не настолько страшны (стандартная библиотека Си++ полагается на шаблоны).
    Вторым языком человек уже съест что угодно, но Си без плюсов — один из худших первых. Си++ не так плох, но Java, по-видимому, лучше.
    Ответ написан
    4 комментария
  • Как решить ошибку LNK2019?

    @Mercury13
    Программист на «си с крестами» и не только
    Судя по всему, эти функции в библиотеках OpenGL. Надо включить в проект opengl32.lib (и, возможно, glu32.lib).
    Ответ написан
  • Как передать вывод?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Чтобы получить ссылку на CMD.EXE, прочитайте переменную окружения COMSPEC.
    2. Не используйте ShellExecute для запуска того, что гарантированно программа, для этого есть CreateProcess.
    3. Да, и не забывайте, что ShellExecute заканчивает работу, когда программа пошла на исполнение. Если нужен результат исполнения — всё тот же CreateProcess + ввод-вывод через каналы + WaitForSingleObject.
    Ответ написан
    Комментировать
  • Принцип работы анимации?

    @Mercury13
    Программист на «си с крестами» и не только
    time — это длительность такта (в игре, очевидно, не просто переменный FPS, но и переменная тактовая частота). Писал такое, правда, не в платформере, а в гоночке.

    rect.left — это точное решение дифура left′ = dx (движение с постоянной скоростью). Очевидно, dx где-то устанавливается по управлению.

    rect.top и dy — это приближённое решение дифура top′′ = 0,005, если снят флаг onGround (полёт под действием силы тяжести). Здесь 0,005 — это ускорение силы тяжести, ось Y направлена вниз. Дифур второго порядка, преобразуется в систему top' = dy, dy′ = 0,005, и то, что в первом случае было точным, здесь приближённое, но приемлемое для игр.

    currentFrame просто прокручивается, чтобы 6-кадровая анимация прошла за 1200 тактов, независимо от частоты. Здесь 1200 = 6 / 0,005.

    Заметьте, dx и dy проходят по разным трактам данных: один — состояние управления, второй — состояние физики персонажа. К тому же что делает dx = 0 и где он ставится не в 0, чтобы не зависеть от частоты автоповтора клавы — непонятно. И много магических констант. Говнокод.

    UPD. Прямые ответы на ваши вопросы.
    1) 6-кадровая анимация, но тут одно из двух. Либо из-за огромного цикла (1200 тактов) явно анимируются не ноги. А может, афтар гонит такты с предельной частотой и потому 1200 тактов действительно пройдут за секунду-две, но тогда это слишком уж явная привязка к скорости компьютера;
    2) в зависимости от номера кадра выбираем тот или иной спрайт на атласе;
    3) dy — скорость, и чтобы откорректировать положение (rect.y), надо прибавить к нему скорость·время.

    UPD2. Кроме того, непонятно, почему в коде анимации нет бега в разные стороны. Хотя из-за крайне простой физики есть подозрение, что жанр — бесконечная бегалка.
    Ответ написан
    3 комментария
  • Нету вывода из массива с указателями из структуры с++?

    @Mercury13
    Программист на «си с крестами» и не только
    Первое и главное. Удивительно, что у вас программа заработала, ведь text.sentences не инициализировано. У меня вылет.

    Ну и извечная ошибка начинающего «плюсовика»: память выделяется, непонятно, кто чем владеет, и, разумеется, память «течёт». Для чего, извините, в Си++ сделали инкапсуляцию, конструкторы и деструкторы?
    Ответ написан
    Комментировать
  • Почему компилятор не видит конструктор?

    @Mercury13
    Программист на «си с крестами» и не только
    Нет, дело не в этом. Линкер не может найти среди OBJ-файлов конструктор MyDb::MyDb. Очевидно, mydb.cpp не скомпилировался или не подключён.
    1) Убедиться, что mydb.cpp включён в проект. 2) Build → Run Qmake.

    Гуглите понятие «единица трансляции» и что делает линкер.
    Ответ написан
    1 комментарий
  • Какое время жизни объекта в std::unique_ptr?

    @Mercury13
    Программист на «си с крестами» и не только
    Уничтоженный unique_ptr уничтожит ваш объект.

    «Уничтожит» — это значит, вызовет деструктор и сделает память доступной менеджеру памяти. Теперь другие указатели, которые смотрят на этот объект, будут «висячими», и при их разыменовании программа может сделать ЧТО УГОДНО.

    А теперь посмотрим, что именно ей угодно. Ваша функция foo() невиртуальная и не имеет дела с полями, ей нужен только this (указатель на объект), который даже не разыменовывается. Она в принципе не может вылететь, даже если десять раз занулить этот объект!

    То, что вы хотите сделать — это семантика std::shared_ptr/weak_ptr.
    std::shared_ptr<ttt> sh1 = std::make_shared<ttt>();
    std::weak_ptr<ttt> we = sh1;
    {
      std::shared_ptr<ttt> sh2 = sh1;
      sh1 = nullptr;
    }
    std::cout << we.expired();  // должно быть true


    UPD. Вот для таких, как ты, и ввели в C++14 функцию std::make_unique, по аналогии с std::make_shared. Просто чтобы было меньше таких ошибок.
    Ответ написан
    Комментировать
  • Разделение строки из символом в массив?

    @Mercury13
    Программист на «си с крестами» и не только
    // считать строчку
    std::string s;
    std::getline(std::cin, s);
    // …и разбираем её потихоньку через поток-строку
    std::istringstream is(s);
    int i;
    std::vector<int> v;
    while (is >> i)
      v.push_back(i);
    Ответ написан
    Комментировать
  • Как выделяется память в классах?

    @Mercury13
    Программист на «си с крестами» и не только
    Examp ex = new Examp ();
    Неверный код, надо Examp* ex = new Examp;

    В случае статического определения (Examp ex2;) — в той памяти, где обычно располагаются объекты. То есть:
    • Если это поле объекта — то в теле объекта, которое может быть где угодно (куча, сегмент данных, стек).
    • Если static/глобальный — то в сегменте данных.
    • Если локальный — в стеке. Конкретно тут локальная переменная, и она будет в стеке.

    В случае динамического определения (Examp* ex = new Examp;) — в «куче».
    В этом примере, кроме операции new, которая заводит объект в куче, видим ещё и указатель, который располагается «там, где обычно» — в теле объекта, сегменте данных или стеке.
    Ответ написан
    Комментировать
  • Bit shift (swap bytes) как это в действительности работает?

    @Mercury13
    Программист на «си с крестами» и не только
    Банально сначала надо unsigned value = 0;
    Вы вроде делаете полный порядок, но начальное присваивание неверное.

    UPD. Проверил в деле — так и есть.
    Ответ написан
    1 комментарий
  • Как проверить существует ли указатель или был удален?

    @Mercury13
    Программист на «си с крестами» и не только
    В Си++11 для этого есть два класса: std::shared_ptr и std::weak_ptr.

    Первый служит для того, чтобы несколько указателей «смотрели» на один объект, и при исчезновении ВСЕХ объект автоматически исчезал.

    Второй «смотрит» на тот же объект, что управляется shared_ptr’ами, но не мешает объекту удаляться. Его можно преобразовать в shared_ptr и тогда уж посмотреть, исчез объект или нет.

    UPD. Вы делаете свой shared_ptr. Тогда, если shared_ptr не NULL — значит, считаем, что объект действительно там есть! А если кто-то удалил своими силами — значит либо shared_ptr глючный, либо кто-то удалил объект в объод семантики умных указателей.

    Кроме того, код по ссылке странный. if (ref_count == 0) — это мы сравниваем указатель с NULL! Написано «переписываем оператор равенства» — по факту переписываем операцию присваивания…
    Ответ написан
    9 комментариев
  • Почему не работает (с++)?

    @Mercury13
    Программист на «си с крестами» и не только
    Надо long long n;
    Дело в банальном переполнении, но profesor08 дал явно неверный ответ.
    Ответ написан
    1 комментарий
  • Что не даёт на C++ писать кроссплатформенные приложения?

    @Mercury13
    Программист на «си с крестами» и не только
    Си — язык очень близкий к железу. Когда мы пишем на Java, мы пишем код под Java-машину. На Си мы пишем код под процессор. Главная проблема, связанная с любыми подобными языками,— отсутствие понимания целевых ОС программистами и тестирования — тестерами. Это нужно, ибо абстрагирование от машины очень тонкое.

    Поскольку перед нами очень тонкая прослойка, абстрагирующая от машины, приходится принимать меры, чтобы код переносился с машины на машину (даже с x86 на x64). Отлично это описано в блоге PVS-Studio.

    В Windows и Linux машина-то одна и та же, но конкретно в Си++ к этому добавляется устаревшая по некоторым вещам стандартная библиотека. Примеры…
    • Поддержка юникодных имён файлов пока не кроссплатформенная.
    • Унаследоваться от std::ostream — ужос такой ещё.
    • Как сконвертировать текст в UTF-8? Загугли и посмотри, какой там вавилон из шаблонов.
    Отсюда огромное количество производителезависимых расширений, чужих библиотек, повторяющих стандартную, и прочее. Важный пункт тут: чужих библиотек, повторяющих стандартную. Если у тебя строки нестандартные и файлы нестандартные — какая тут кроссплатформенность?
    Ответ написан
    Комментировать
  • Наследование оператора присваивания (=), как это сделать?

    @Mercury13
    Программист на «си с крестами» и не только
    Почему не прописывается автоматически? А потому что в Test2 будет больше полей, и никто, кроме вас, программиста, не знает, что с ними делать.

    Но никто не мешает самому написать операцию =, например.
    class Test2 : public Test
    {
    private:
      typedef Test Super;
    public:
      Test2& operator = (const Test& x);
    };
    
    Test2& Test2::operator = (const Test& x)
    {
      Super::operator = (x);
      // придумай, что сделать с недостающими полями
      return *this;
    }
    Ответ написан
    3 комментария
  • В чем суть WinApi?

    @Mercury13
    Программист на «си с крестами» и не только
    Windows API — это самый низкоуровневый интерфейс Windows, доступный прикладному программисту — в том плане, что он на долгосрочной поддержке и не изменится с Windows 11.

    Поверх Windows API работают все BOOST и STL.

    Пример: читать файл в 130 мегабайт по одному байту. Добавив асинхронного чтения через OVERLAPPED, я сумел это сделать менее чем за 2 секунды (это был поток общего назначения с виртуальными read(), write() и seek(); специализированный прикладной буфер даст ещё выигрыша, но и это хорошо). То же самое через FILE* — не дождался.

    Пример второй, всё те же файлы. Дело в том, что Excel захватывает свои файлы на всё время, пока он открыт. Закрывать? — плохой выбор. Добавив один флажок в CreateFile, документы всё-таки стало возможным открывать при работающем Excel.
    Ответ написан
    2 комментария
  • Как передать вектор в функцию?

    @Mercury13
    Программист на «си с крестами» и не только
    Раз мы изменяем наш вектор — то по неконстантной сцылке.

    void add (int n, std::vector<int>& vec){
        vec.push_back(n);
    }
    
    std::vector <int> myVec;
    add(5, myVec);
    Ответ написан
    Комментировать