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

    @romancelover
    программист C++ под Linux
    Скорее всего имеется в виду конструктор и деструктор класса, то есть функции, отвечающие за инициализацию объекта и освобождение связанных с ним ресурсов.
    Ответ написан
    Комментировать
  • Почему ГПСЧ нужно инициализировать в main()?

    @romancelover
    программист C++ под Linux
    Потому что в srand() будет передаваться одинаковое число. Функция time возвращает число секунд от начала 1970 года, её значение меняется раз в секунду, а цикл программы выполняется намного быстрее.
    Ответ написан
    Комментировать
  • Правильное применение const?

    @romancelover
    программист C++ под Linux
    Параметры функции, объявленные как const ссылки, могут инициализироваться результатом выражения (rvalue), а обычные ссылки, без const - только присваиваемому выражению (lvalue). В С++11 появились также rvalue ссылки, которые могут быть изменяемыми. Сложные объекты лучше передавать в функции по ссылкам (или указателям), чтобы избегать копирования.
    Значит если параметр передаётся по ссылке, то ссылка с const может быть входным параметром функции, а без const - скорее всего выходным (или двунаправленным, который передаётся в функцию и там модифицируется, и служит результатом выполнения). Параметр по ссылке без const может быть входным, но это неудобно - в нём нельзя передать выражение, а только переменную (или в общем случае lvalue). И ещё это сбивает использующих функцию программистов с толку, наводя их на мысль, что параметр по ссылке должен модифицироваться внутри вызываемой функции.

    Сразу понятно назначение параметров, какой параметр входной, какой выходной. Параметр по значению всегда входной, по указателю - аналогично ссылке, с const только входной, без const скорее всего выходной (но не обязательно).
    rvalue ссылки нужны в том случае, если нужно сохранить объект, переданный в функцию, без копирования (объект по const ссылке пришлось бы скопировать внутри функции, а это неоптимально). Параметр по rvalue ссылке - тоже входной параметр функции, как и по const ссылке.
    Ответ написан
    1 комментарий
  • Почему функция не видит public переменную из другого класса?

    @romancelover
    программист C++ под Linux
    mWindow определён в классе Window, а обращаются к нему в другом классе Camera, в котором члена mWindow нет. Как компилятор узнает о связи между классами Camera и Window, чтобы один использовал члены другого?
    Можно обратиться к нему в том случае, если Camera будет наследником Window (но в данной ситуации это скорее всего не нужно), или в Camera будет член типа Window или указатель на него (Window* _window) тогда _window->mWindow будет допустимо.
    Ответ написан
    Комментировать
  • Как скормить компилятору такую шляпу?

    @romancelover
    программист C++ под Linux
    У меня компилятор (g++ 10.2.0) сам подсказывает, чего не хватает:
    test.cpp: В конкретизации «void Sorts::PrintArray(int) [с T = int]»:
    test.cpp:161:21: required from here
    test.cpp:118:26: ошибка: зависимое имя «std::__cxx11::list::iterator» разбирается как не тип, но конкретизация дает тип
    118 | for (std::list::iterator it = arrayList.begin(); it != arrayList.end(); it++)
    | ^~~~~~~~
    test.cpp:118:26: замечание: задайте «typename std::__cxx11::list::iterator», если подразумевается тип

    И так во во всех четырёх местах с итераторами. Это связано с тем, что std::list::iterator - это не обычный тип, а шаблонный, а по правилам языка С++ требуется указывать, что этот шаблон должен разбираться именно как тип.

    Это нужно потому, что не всегда возможно определить, является ли подстановка шаблона типом или значением.
    void foo(const T& t)
    {
       // declares a pointer to an object of type T::bar
       T::bar * p;
    }
    
    struct StructWithBarAsType
    {
       typedef int bar;
    };
    
    struct StructWithBarAsValue
    {
        static int bar;
    };

    Непонятно, T::bar это тип или значение? Если в шаблон передать StructWithBarAsType, то это могло бы быть типом, если StructWithBarAsValue - то значением. Поэтому по умолчанию компилятор принимает такую запись за значение (а раз такого члена iterator в std::vector нет, то компилятор ругается на это), а если указать typename, то он будет знать, что это именно тип.
    Ответ написан
    Комментировать
  • Как решить задачу на поиск простых множителей?

    @romancelover
    программист C++ под Linux
    Программа пытается проверять на делимость все числа от 600851475143 подряд, и на этом зависает (слишком много проверок нужно выполнить). Переменная С уменьшается только вычитанием единицы.
    И считает она не то, что нужно.
    Я поправил так (самый простой код, можно ещё оптимизировать, например, проверять числа до корня квадратного из делимого, а не до делимого). Но для новичка сойдёт.
    #include <iostream>
    int main()
    {
        std::cout << "Hello World!\n";
        unsigned long long C = 600851475143;
        unsigned long long temp=3;
        if((C % 2) == 0)
        {
            C = C / 2;
            std::cout << 2 << std::endl;
        }
        while  (C > 1)
        {
            if (C % temp == 0) {
                C = C / temp;
                std::cout << temp << std::endl;
            }
            temp=temp+2;
        }
    }

    Вывод:
    Hello World!
    71
    839
    1471
    6857
    Ответ написан
  • Есть ли метод ограничивающий скорость интернета для определённого процесса? Если нет, как это можно реализовать?

    @romancelover
    программист C++ под Linux
    https://unix.stackexchange.com/questions/328308/ho...

    Это может быть только специфичный для каждой операционной системы API. В Linux этого можно добиться через создание cgroup, назначение его процессу и создание дисциплины обработки пакетов для этого cgroup.
    Ответ написан
    Комментировать
  • Как выводить переменную в MessageBox?

    @romancelover
    программист C++ под Linux
    В языках С и С++ и WinApi LPCTSTR - это просто указатель на последовательность символов в памяти. Прибавление к нему числа не меняет последовательность символов, а только переводит позицию указателя. Поэтому код в примере выведет строку с 10-го символа (считая с 0), а не допишет число к строке.
    Чтобы добиться нужного результата, нужно создать новую последовательность символов и передать указатель на неё в функцию. На Си можно использовать функции wcscpy, wcscat и _itow (или как её аналог в вашем компиляторе называется) или wsprintf (неудобно тем, что нужно следить за количеством символов, выделяемых под строку), на С++ лучше создать std::wstring (wstring так как тут LPCTSTR, и длинные символы, и программа собирается в Unicode режиме), записать туда строку и число (можно при помощи wostringstream), а потом передать в MessageBox указатель с помощью c_str().
    Ответ написан
  • Как убрать ошибку?

    @romancelover
    программист C++ под Linux
    Под Linux программа собирается такой командой:
    gcc tcl.c -ltcl -ltk -o tcl
    и запускается нормально.

    Под другими ОС аналогично, надо указать пути к библиотекам Tcl и Tk. В Linux -ltcl это просто сокращение для libtcl.so, а в Windows, насколько помню, указываются LIB-файлы.
    Ответ написан
    Комментировать
  • Возможно ли локально в пределах заголовочного файла импортировать функции из dll?

    @romancelover
    программист C++ под Linux
    Можно оставить в заголовочном файле только обёртки, а импортируемые функции объявить только в cpp файле с реализацией этих обёрток.

    *.h:
    template<> int f(float x) ;
    template<> int f(double x);
    *.cpp:
    extern "C" int lib_ff(float x);
    extern "C" int lib_fd(double x);
    template<> int f(float x) { return lib_ff(x); }
    template<> int f(double x) { return lib_fd(x); }
    Ответ написан
    Комментировать
  • Как исправить ошибку унарного оператора?

    @romancelover
    программист C++ под Linux
    В С++ унарный оператор X определяется либо как operatorX без параметров внутри класса, или как функция operatorX с одним параметром вне класса. Перенесите operator- вовне класса, и добавьте friend, аналогично тому, как это сделано для operator>.
    Ответ написан
    Комментировать