Ответы пользователя по тегу C++
  • POSIX threads + usleep - почему не работает?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    usleep имеет код возврата и устанавливает errno в случае ошибки. Воспользуйтесь этим.
    Ответ написан
    Комментировать
  • Почему inline функция класса C++ медленнее обычной inline функции?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Вопрос, почему первый вариант (sum(v1,v2,v3)) медленнее чем второй (direct_sum(v1,v2,v3)) примерно на 10%?

    Потому что вы не показали ни опций компилятора, полной програмы, ни способа измерения времени.
    Откомпилировав оба примера с вашими опциями я получил идентичный ассемблерный код для цикла вычислений.
    Ответ написан
    6 комментариев
  • Кодек LAME mp3 выдает ошибки, как исправить?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Покажи полный исходник, чтобы его можно было скомпилировать.
    Как решить эту проблему? Возможно, установить другую версию gcc?

    Только если ты компилировал lame сам, и то вряд ли.
    Ответ написан
  • Почему Wav файл не корректный?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Судя по заголовку это должен быть 8000Гц 16бит моно PCM.
    Но byte rate (значение 0x1484 по смещению 28) не соответствует формату: должно быть 8000 * 1 * 16 / 8 = 0x3e80.
    Ответ написан
    Комментировать
  • Как реализовать наследование от ветви интерфейсов и базовой реализации корневого интерфейса?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    А почему не просто
    class B :  public IB, A
    {
    public:
            void f1() {
                    A::f1();
            }
            void f2() {
                    std::cout << "f2" << std::endl;
            }
    };
    Ответ написан
  • Как правильно запутить конструктор родителя внутри наследника?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    #include life_node.h
    
    LifeNode::LifeNode():
          Node<ros_johnny5::servoMsgArray, ros_johnny5::robotState>(SIZE_MESSAGE_BUFFER, TOPIC_SERVO_CONTROL, TOPIC_ROBOT_STATE),
          mInMotion(1),
          mGreetingFlag(0)
    {
    
    }

    Кроме того, конструктор Node должен либо быть определён в файле node.h (или любом другом, который должен быть подключен к моменту вызова конструктора), либо явно инстанцирован для использованных вами шаблонных параметров. Это относится также и ко всем методам класса Node.
    Ответ написан
    Комментировать
  • Как вернуть копию объекта?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    По сути своей два вопроса будут...
    Object getMeAnyObject(int i)
      {
        return listOfObject.at(i);
      }

    Я хочу вернуть копию объекта из контейнера, а не ссылку. Верен ли мой код?

    Верен, если вы правильно расставили теги, и это действительно C++. Правда, в этом случае здесь listOfObject << new Object(); написана какая-то ерунда.
    Второго вопроса не увидел.
    Ответ написан
  • Как добавить поддержку range-based цикла в свой класс?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    iterator_t
    const_iterator_t

    Суффикс _t зарезервирован, лучше его не использовать в своём коде.

    const_iterator_t cbegin()
    const_iterator_t cend()

    В стандартных контейнерах эти методы -- const.

    при каких условиях будет вызваны cbegin() и cend()

    Думаю, что только явно программистом, руками.

    с какой целью они существуют в std::list и др. типах

    Чтобы можно было легко получить константный итератор из неконстантного контейнера.
    Ответ написан
  • Какой смысл внешней компоновки имени класса в C++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Но у меня сразу возникает мысль. Если компоновка имени внешняя, то это значит, что это имя доступно в других единицах трансляции. Однако, как с функциями не работает:
    foo.cpp
    ----------
    void foo() {}
    
    
    bar.cpp
    ----------
    void foo();
    
    void bar()
    {
       foo();
    }

    Почему же? Работает.

    То есть я не могу написать так:
    A.cpp
    ----------
    class A
    {
    };
    
    
    B.cpp
    ----------
    class A;
    
    void foo(A a) // A is an incomplete type
    {
    }


    Но этот пример не имеет никакого отношения к компоновке имени A. Вы не можете написать так, потому что операция передачи по значению недоступна для неполного типа. Но уже вот так вполне можно написать:

    A.cpp
    ----------
    class A
    {
    };
    
    
    B.cpp
    ----------
    class A;
    
    void foo(A& a) // A is an incomplete type, but who cares
    {
    }


    Вопрос: какой смысл тогда во внешней компоновке имени класса?

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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Можно сделать так:
    Elevator реализует приватный интерфейс ButtonControlled с одним публичным методом -- decide. Приватность интерфейса гарантирует, что только Elevator сможет дать его кому захочет. Button получает от Elevator не ссылку на Elevator а ссылку на ButtonControlled, в котором счастливо вызывает decide.
    Типа того:
    class ButtonControlled
    {
    public:
      virtual void decide() = 0;  
    };
    
    class Elevator : ButtonControlled
    {
    private:
      Button* button;
      virtual void decide();
    };
    
    class Button
    {
    private:
      ButtonControlled* controlled;
    public:
      Button(ButtonControlled &controlled);
      void push()
      {
        controlled->decide();
      }
    };
    
    Elevator::Elevator()
    {
      button = new Button(*this);
    }
    Ответ написан
    2 комментария
  • Как засунуть n - мерный массив в аргумент функции?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Ну вот, опять знатоки советуют добавить звёздочек и указателей на указатели ):

    Все примеры дальше передают в функцию трёхмерный массив и присваивают v значение его элемента p[1][2][3].

    Если функция принимает массив фиксированных размерностей, то прямо так можно и написать:
    int f(int p[][20][30])
    {
        int i = 1, j = 2, k = 3;
        int v = p[i][j][k];
    }
    ...
    int p[10][20][30];
    f(p);

    Первую размерность (самую старшую) можно опустить.

    Если же нет, то перед вами следующий выбор:

    - у вас старый стандарт С (до С99) -- передавайте указатель на самый первый элемент и значения размерностей. Внутри функции пересчитывайте набор индексов многомерного массива в линейный индекс:
    int f(int *p, int n2, int n3) // p[][n2][n3]
    {
        int i = 1, j= 2, k = 3;
        int v = p[(((i * n2) + j) * n3) + k]; // v = p[i][j][k];
    }
    ...
    int p[10][20][30];
    f(&p[0][0][0], 20, 30);


    - у вас С99 или новее: воспользуйтесь поддержкой языка:
    int f(int n2, int n3, int p[][n2][n3])
    {
        int i = 1, j = 2, k = 3;
        int v = p[i][j][k];
    }
    ...
    int p[10][20][30];
    f(20, 30, p);
    Ответ написан
    5 комментариев
  • Как сделать сортировку вектора структур по произвольному полю?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Сделайте как сделано в STL: передайте функтор, сравнивающий два объекта, а он уж пусть сравнивает что пользователю нужно.
    Типа второго шаблона тут: en.cppreference.com/w/cpp/algorithm/sort
    Ответ написан
    Комментировать
  • Как закрепить длину буфера записи в bass.dll?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Типовое решение этой проблемы -- накапливать данные у себя и обрабатывать, когда накоплено столько, сколько нужно. Совсем тупая реализация на С:

    char *buf;
    size_t buf_sz;
    ...
    BOOL CALLBACK DuffRecording(HRECORD hangle, const void *buffer, DWORD lenght, void *user)
    {
      buf = realloc(buf, buf_sz + length);
      memcpy(buf + buf_sz, buffer, lenght);
      buf_sz += length;
      return TRUE;
    }
    
    // эту функцию нужно вызывать когда есть новые данные,
    // например, после каждого вызова DuffRecording
    void chunk_handler(void)
    {
      size_t offset = 0;
      while (buf_sz >= offset + CHUNK_SIZE) {
        do_something_with_data(buf + offset);
        offset += CHUNK_SIZE;
      }
      if (offset) {
        memmove(buf, buf + offset, buf_sz - offset);
        buf_sz -= offset;
      }
    }
    
    // эта функция будет вызвана с p указывающим на буфер длиной CHUNK_SIZE
    void do_something_with_data(void *p)
    {
      ...
    }
    Ответ написан
    9 комментариев
  • Почему при удалении значения не присваеваеться последнее id?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Перестаньте пожалуйста помечать вопросы о базах данных тегами C++ и QT.
    Ответ написан
    Комментировать
  • Как грамотно преобразовывать информацию из byte в int?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Капец насоветовали.
    При условии, что endianness вашей машины такой же, как у данных, я бы делал так:

    char *recbuf = ...; // <-- входные данные
    int16_t *samples = (int16_t*)recbuf; // <-- они же, в виде знаковых 16-битных чисел.

    Всё. Обращайтесь к samples.
    Ответ написан
    Комментировать
  • Почему при передаче указателя на структуру присвоенное значение в функции сбрасывается?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    А зачем вы в SomeClass::someFunc меняете значения указателей (локальные для функции), вместо того, чтобы менять значения, на которые они указывают? Типа того:
    void SomeClass::someFunc(SYSTEMTIME * _minDate, SYSTEMTIME * _maxDate){
      SYSTEMTIME minDate, maxDate;
      std::vector<SYSTEMTIME> dates;
      ...
        minDate = dates[0]; // тут все хорошо. Новые значения присвоены
        maxDate = dates[1];
      ...
      *_minDate = minDate;
      *_maxDate = maxDate;
    }

    Ну, или если уж необходимо действительно указатели менять, то, например, так:
    void SomeClass::someFunc(SYSTEMTIME * & _minDate, SYSTEMTIME * & _maxDate){
      SYSTEMTIME minDate, maxDate;
      std::vector<SYSTEMTIME> dates;
      ...
        minDate = dates[0]; // тут все хорошо. Новые значения присвоены
        maxDate = dates[1];
      ...
      // что-то сделать с объектами, на которые указывают _minDate и _maxDate, например освободить
      _minDate = new SYSTEMTIME(minDate); // _minDate  присвоен указатель на новый объект.
      _maxDate = new SYSTEMTIME(maxDate); // проветил, _minDate  и _maxDate дейсвтиетльно какие нужно.
    }
    Ответ написан
    1 комментарий
  • Как сделать зеркало, sdd и hdd?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    kokas какое отношение ваш вопрос имеет к С++ и программированию?
    Для кеширования одних блочных устройств другими под linux есть bcache и flashcache, но вы даже не указали, что у вас будет за ОС.
    Ответ написан
    Комментировать
  • Где хранятся закрытые данные базового класса при обращении к ним через производный класс (C++)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    так как i - закрытый член базового класса, в производном классе его нет

    Ошибка здесь. Наследование выражает отношение "являться": наследник является всеми своими родителями. Объект класса B является и объектом класса А и содержит все его поля и методы. Но не ко всем ним имеет доступ.

    ответа на свой вопрос я не нашел

    Ответ на ваш вопрос в разделе 10 Derived Classes стандарта С++, который в редакции 98 года говорит:
    Unless redefined in the derived class, members of a base class are also considered to be members of the derived class. The base class members are said to be inherited by the derived class.
    Ответ написан
    Комментировать
  • Как правильно использовать LocalFree?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    pDataIn -- это In-параметр, функция его не трогает и ей всё равно как вы его выделили. Освобождать его нужно согласно тому, как он был выделен вами.
    Ответ написан
    6 комментариев
  • Почему после вызова t1 = std::move(t0) вызывается деструктор t0?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Насколько я понял идею std::move, вызов в return move(t) должен осуществить перемещение данных класса t в t1 без вызова деструктора.

    Насколько я понимаю идею std::move, вы получаете вызов конструктора T(T&&) вместо T(const T&), в котором вы сами должны переместить (или не перемещать) нужные поля в создаваемый объект. После перемещения оригиналы полей нужно подходящим способом "обнулить". Деструктор локального объекта, выходящего из области видимости будет вызван в любом случае.

    В реальной программе T содержит объект fstream, а в деструкторе осуществляется закрытие потока.

    Насколько я вижу, std::fstream поддерживает конструирование из ссылки на rvalue.
    Ответ написан
    Комментировать