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

    @rPman
    Можно, если размер во время инициализации - константа, описать тип через шаблоны
    template<typename T, size_t size>
    class MyArray
    {
    T data[size];
    ...
    }
    докинув методов для работы с массивом, включая оператор[]... а еще лучше, воспользоваться готовым std::array
    Ответ написан
  • Как вернуть двумерный массив?

    @rPman
    Помню очень очень давно, когда мне нужен был объект двумерный массив с заданными константами размерами (и достаточно маленький чтобы не перегружать стек), а так же мне не нравилось что двумерные массивы требовали дополнительный массив ссылок, который еще нужно было инициализировать, я создавал класс (формально два, так как перегружать оператор [] можно только один раз, для второй перегрузки нужен класс посредник), симулирующий поведение двумерного массива на одномерном, при этом сам массив определялся не как ссылка на него, а как собственно сам объект
    нытье
    сейчас я код свой старый не найду, мне лень но я попросил chatgpt все написать, и о чудо, bing copilot не справился (отвратительно, майкрософт испортила хороший инструмент) хотя он понял концепцию но умудрился наделать кучу ошибок, пришлось чинить, в прошлом году он прекрасно с таким простым кодом справлялся. Не так, если воспользоваться площадкой для ботов coze, там используется gpt4, то результат получается верным (нет он тоже напортачил в подсчете смещения в массиве), это именно майкрософтовский сопилот тупой
    template<typename T,size_t RowNum, size_t ColNum>
    class Array2D {
    private:
    	T arr[RowNum*ColNum];
    
    public:
    	class Proxy
    	{
    	private:
    		T* _arr;
    
    	public:
    		Proxy(T arr[]) : _arr(arr) {}
    
    		T& operator[](size_t index)
    		{
    			return _arr[index];
    		}
    	};
    
    	Proxy operator[](size_t index)
    	{
    		return Proxy(&arr[index*ColNum]);
    	}
    };
    
    typedef Array2D<int, 3, 5> mas35;
    
    mas35 test()
    {
    	return *(new mas35); // с этим нужно быть предельно осторожным, так как бездумно можно получить утечки памяти
    }
    
    int main()
    {
    	mas35 a=test();
    	a[1][0] = 5;
    // ...
    	return 0;
    }
    Ответ написан
    Комментировать
  • Как сделать удаленный доступ для к программе под windows для нескольких пользователей (аля RDP)?

    @rPman
    На текущий момент, если пользователей - до десятка (больше сложнее чисто технически) проблему одновременной работы нескольких пользователей за одним компютером можно решить аппаратным способом. А точнее с помощью ibik aster.

    При этом, работать все будет нативно, без прослоек, т.е. можно запускать 3d приложения/игры, никаких лагов и задержек.

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

    Необходимо к одному компьютеру подключить нужное количество мониторов (видеокарты обычно имеют 3-4 порта, можно в одну машину вставить любые самые дешевые gpu, хоть через рейзеры), клавиатур и мышек (usb удленители, в т.ч. есть по ethernet кабелю до 200 метров). Приложение ibik aster (примерно в 100 раз дешевле лицензий на windows server) и настраиваешь рабочие места - каждому свой монитор, клавиатуру, мышку, звуковуха (если использовать телевизор с динамиками, то по hdmi будет идти звук) и даже свой ip адрес (там как то не совсем корректно реализовано но в каких то случаях работает).

    На сегодняшний день это самый лучший способ (с точки зрения денег) организации рабочих мест 'одно железо - несколько пользователей', без особых проблем с совместимостью (очень небольшое количество приложений могут специально запрещать себя запускать одновременно, но я помню, даже игры у меня шли под разными пользовательскими профилями, если их устанавливать в разные каталоги на диске, тупо дублируя). А для дома так вообще максимальная рекомендация - в подавляющем большинстве случаев активно ковыряющемуся отдельный компьютер, а остальным - второй, всеравно 99% времени это браузер и пара игрушек, друг другу мешать не будут.

    p.s. Само собой, то же самое можно сделать на linux бесплатно. multiseat штатными утилитами если 1 gpu на одно рабочее место, если же на одну видеокарту нужно несколько рабочих мест, тогда сложнее, с помощью xephyr (это xserver в окне) и чуть чуть скриптов.

    upd. кстати, это можно совместить с vnc/rustdesk/... настраиваешь фейковые мониторы (заглушки стоят 100-200р), без клавиатуры и мышки, каждое рабочее место настраиваешь свой vnc, и к этому монстру можно подключаться удаленно по сети. Тонкие клиенты можно сделать хоть из смартфона/смарт_тв
    Ответ написан
    1 комментарий
  • Возможно ли автоматически конвертировать большой проект с Java на C++?

    @rPman
    Все верно тебе ответили - ручками.

    Но, начать можно с кодогенерации с помощью j2c, особенно если у тебя полностью самописный код а не использование сторонних jni библиотек (с ними будет сложнее), это конвертер Java в C код с последующей ее компиляцией в нативный.

    Результат будет хуже чем если все делать руками но возможно самую тупую но объемную работу можно будет взять от туда.

    upd. я бы не сбрасывал со счетов ИИ, он дает неожиданные результаты, полностью работу пока еще на него я бы не перекладывал, но вот что то простое но объемное - почему нет.

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

    @rPman
    в твоем случае просто - делать i--, само собой, если условие пропуска содержит учет номера шага, то для этого завести дополнительный счетчик настоящих шагов

    Если что под твою задачу лучше делать цикл while и считать количество 'новых слов' а не количество шагов, зачем тебе эти шаги
    Ответ написан
    Комментировать
  • Как создать exe файл с интерпретатором angel script?

    @rPman
    AngelScript sdk это и есть набор инструментов и библиотека по компиляции и запуску скриптов с интеграцией их в своем c++ приложении.

    Ответ я не знаю но я открываю документацию и там все красиво с примерами написано

    Вот так ты компилируешь скрипт
    Вот так ты запускаешь метод в скрипте

    Внутри sdk в каталоге sdk/samples есть примеры проектов visualstudio
    Ответ написан
    Комментировать
  • Что означает T()?

    @rPman
    T() вызовет конструктор по умолчанию для типа T, тут это переменная шаблона, т.е. тот тип что указан при определении переменной класса List<имя_типа_или_класса>, который собственно тут описан.

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

    Если честно у меня вопрос, что будет если тип T будет указан скалярный, типа int, определено ли значение по умолчанию для таких типов?
    upd. погуглил пишут да, в контексте шаблонов это нормально и значение по умолчанию определено
    Ответ написан
    4 комментария
  • Как сделать так, чтобы математический знак + не был функцией?

    @rPman
    В c++ существует способ переопределить поведение операторов для своих классов, такие операторы как ++ и -- это unary операторы (могут располагаться как перед оператором так и после с различным поведением) но невозможно изменить ситуации как именно + и - могут быть унарными, так как из размещение в режиме unary допускается только перед переменной.
    // можно
    выражение++
    // но нельзя
    выражение+
    // можно
    +выражение


    чтобы переопределить унарный + нужно написать
    MyClass operator+()
    {
      // выполнить действия с this
      return MyClass(value);
    }


    На сколько я знаю твой код (nujno==+) никак нельзя сделать валидным (препроцессор кстати тоже не позволит переопределить поведение +), да и == - бинарный оператор (нет варианта с его одинарным использованием)
    Ответ написан
    Комментировать
  • Имеется ли в C++ данный синтаксис?

    @rPman
    Смотрим исходники (как же там неудобно искать, проще было склонировать и найти в файлах)

    Видим что этот дефайн ожидает первым аргументом X часть имени определяемых им переменными и функциями, а вторым, аргументы перед ними, т.е. в твоем примере это static (для макросов нет никакой разницы что в аргументах, лишь бы разбиралось на лексемы даже на скобки кстати пофиг)

    Описание аргументов ,... это variadic т.е. можно несколько аргументов писать в вызове макроса, они все передадутся как есть (есть разные способы их развертывания)

    Вот к примеру твой пример развернется в
    static vnet_feature_arc_registration_t vnet_feat_arc_ip4_unicast;
    static void __vnet_add_feature_arc_registration_ip4_unicast (void)
      __attribute__((__constructor__)) ;
    static void __vnet_add_feature_arc_registration_ip4_unicast (void)
    {
      vnet_feature_main_t * fm = &feature_main;
      vnet_feat_arc_ip4_unicast.next = fm->next_arc;
      fm->next_arc = & vnet_feat_arc_ip4_unicast;
    }
    static void __vnet_rm_feature_arc_registration_ip4_unicast (void)
      __attribute__((__destructor__)) ;
    static void __vnet_rm_feature_arc_registration_ip4_unicast (void)
    {
      vnet_feature_main_t * fm = &feature_main;
      vnet_feature_arc_registration_t *r = &vnet_feat_arc_ip4_unicast;
      VLIB_REMOVE_FROM_LINKED_LIST (fm->next_arc, r, next);
    }
    static vnet_feature_arc_registration_t vnet_feat_arc_ip4_unicast

    Заметь что последняя строчка не завершена, нет ";", значит если после вызова этого макроса поставить = ... то пойдет определение значения переменной vnet_feat_arc_ip4_unicast
    а запись через { .имя_поля=значение,...} это удобный способ инициализировать структуры
    Ответ написан
    1 комментарий
  • Как лучше всего реализовать хранение "шаблонов" файлов?

    @rPman
    Хранение блобов в файле программы (оно будет мапиться на адресное пространство и читаться эффективнее fread) в .data секции, создать объектные файлы с помощью objcopy или генерировать константы массивов с 0xXX с помощью xdd

    https://caiorss.github.io/C-Cpp-Notes/resources-ex...
    Ответ написан
    Комментировать
  • Как скрыть адрес вызываемой функции в C++?

    @rPman
    В коде, указанном в вопросе написана белиберда
    В конструкторе предлагаешь сделать присваивание
    vProtect = Protect;
    глобальной переменной vProtect имя класса Protect (потому что у тебя Protect и класс и переменная типа cProtect, (то что компилятор тебе это позволил уже бардак), если переименовать cProtect мембер Protect в protect (как рекомендует большинство code styling - имена классов с большой буквы, имена переменных - с маленькой, чтобы не запутаться), а еще тип vProtect у тебя - указатель, а Protect - нет, если будут оба указатели то само собой все будет собираться, но все равно смысла это иметь не будет.
    -----------------------

    Теперь про твой вопрос в заголовке, почти ничего не имеющий общего с текстом вопроса:
    Как скрыть адрес вызываемой функции в C++?
    в контексте обфускации, подразумевается что по декомпилированному исходному коду должно быть не ясно, какой именно метод будет вызываться (т.е. для анализа требуется отладка, что сложнее/дороже), значит хранить адреса методов нужно в каких то переменных, например массивах, а выбор следующего вызываемого метода делать на основе каких то вычислений по коду.

    В c++ для этого реализован класс std::function, пример использования для вызова именно метода класса (для простоты пример без аргументов но с аргументами все то же самое, надеюсь ты понимаешь, что у тебя должны быть одинаковые аргументы и типы во всех методах, или должны быть группы для разных типов, но чем больше групп тем проще анализ кода, иначе тупо по типам и количеству аргументов все можно будет понять)
    // определяем класс
    class MyClass
    {
      public:
      void myFunA(){std::cout<<"A";};
      void myFunB(){std::cout<<"B";};
    };

    однократно где то инициализируешь массив адресов функций (никто не мешает по коду это перемешивать)
    std::function<void(MyClass*)> functions[]={&MyClass::myFunA,&MyClass::myFunB};

    вызов метода по номеру x
    MyClass obj;
    functions[x](&obj);
    Ответ написан
    3 комментария
  • Как узнать размер незаполненного массива в c++?

    @rPman
    для массивов изменяемого размера используй std::vector (а так же для разнообразия std::deque, std::list, а если к примеру значения уникальные то std::map а вообще контейнеров списков в c++ много)

    это примерно в 2-3 раза медленнее и кушает память, бонусом будет контроль выхода за границы.

    само собой можно на основе обычных c-массивов и своего класса запилить под свои нужды и логику, например хранить рядом с массивом его текущую длину, при превышении текущего размера пересоздавать вдвое большего размера, а при двухкратном уменьшении - соответственно уменьшать)
    Ответ написан
    Комментировать
  • Как правильно подключать файлы?

    @rPman
    #pragma once
    в начале файла предотвращает его повторную загрузку

    В c и c++ принято разделять описание своих типов и классов на заголовочный файл .h и собственно код .cpp
    Заголовочные файлы подключаешь с помощью #include "xxx.h", а вот файлы cpp компилируются отдельно в .o (.obj для майкрософтовского компилятора) объектные файлы и из этих объектных файлов линкер собирает итоговый exe-шник

    Все среды разработки делают сборку автоматически из твоих .cpp файлов, вызывая для каждого компилятор только когда они изменились и автоматически отслеживают взаимозависимости .h файлов (т.е. если два из 100 твоих файлов подключили xxx.h то при его измении будет пересобраны только эти два файла). Вручную эти зависимости описываются с помощью выбранной системы сборки, например make, там указываешь какой cpp файл от каких .h файлов зависит

    p.s. формально ты можешь подключить напрямую .cpp файл, препроцессор вообще их не различает, но из-за взаимозависимостей тебе будет сложно это делать
    Ответ написан
    Комментировать
  • Что написать на C++ для практики?

    @rPman
    Реши любую задачу с многопоточностью и общей памятью, какой-нибудь сервер например.
    Или, к примеру, возьми тяжелый проект типа исходники браузера firefox/chromium и модифицируй их полезным образом (в этой области даже простая возможность настроить окружение, чтобы собрать этих монстров из исходников - уже плюс, а уж способность найти в исходниках нужное место и подправить - однозначно велком).
    p.s. помню не осилил отладку openjdk jni кода (для этого нужно не просто настроить окружение для сборки java но и настроить отладку в ней) и искал баг в портируемом коде jni, роняющем java, по старинке логированием, полагаю если сумеешь настроить сборку и отладку, можно наверное сразу на мидла претендовать.

    Люди, способные не просто собирать код из последовательных блоков а способные мыслить комплексно - уже показатель.

    p.s. если работодатель ищет c++-ника, его явно не интересуют конечные задачи, это могут запилить рядовые программисты на любом другом высокоуровневом языке программирования, а интересуют не сами знания, а интеллект
    Ответ написан
  • Можно ли выделить память определенного размера?

    @rPman
    Если у тебя в итоге размер этого buf будет известен на этапе компиляции, то можно воспользоваться шаблонами
    template<int SIZE> struct MyStruct {
      int a;
      char buf[SIZE];
    };
    ...
    auto x=new MyStruct<10>; // x - указатель на MyStruct
    или
    const int size=10;
    auto x=new MyStruct<size>;
    ...
    delete x;
    Ответ написан
  • Вопрос по оформлению кода C++?

    @rPman
    Coding style должен быть таким, как определено в вашей команде
    Если это твоя команда - решение принимать нужно после общения со своей командой, выбрав тот стиль, наименее конфликтующий с их стилями.

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

    @rPman
    Так чем не нравится шаблон?

    окей, создай промежуточную функцию, где определи весь свой код со значением твоего enum в параметрах, можно даже пометить ее inline чтобы наверняка, если не доверяешь автоматической оптимизации

    temlate <typename Derived1Enum> inline void Derived1::_someMethod(const Derived1Enum _state) {
    ...одинаковый код...
    state = _state
    ...одинаковый код...
    }
    void Derived1::someMethod() {
    _someMethod(Derived1Enum::SomeStateDerived1)
    }
    void Derived2::someMethod() {
    _someMethod(Derived2Enum::SomeStateDerived2)
    }

    upd. подправил с использованием шаблона
    Ответ написан
  • Почему запускается деструктор в данном примере?

    @rPman
    Сам copy никак не вызывает деструктор
    деструктор будет вызван автоматически по завершению области действия места где объект был создан, т.е. после завершения main

    Если же ты добавляешь *this в return Copy то у тебя возникает вызов деструктора этого возвращенного объекта, который не используется, а затем еще раз по завершению программы, собственно программа у тебя будет мусор на экран выводить вместо ожидаемого hi.

    Добавь в деструктор вывод на экран "destructor", увидишь

    Причина (если честно для меня не очевидная) в том что ты мешаешь два подхода - работа с объектами и работа со ссылкой на объект, преобразованный в сам объект (return *this), рекомендуется не мешать эти два подхода
    Ответ написан
    Комментировать
  • Почему разный результат байт?

    @rPman
    У тебя разные типы данных и соответственно размеры int это 4 байта (или 8 в зависимости от компилятора и архитектуры) и char - 1 байт
    int in_stream[100]
    и
    char packet_data[100];

    memcpy работает с байтами а значит копирует только часть данных
    Ответ написан
  • Есть ли что то вроде api, который позволял бы компилировать программу из под исполняемого файла?

    @rPman
    почему нет, все есть, та же libcxx

    так же для работы с исходниками существуют библиотеки, позволяющие проанализировать код и работать с его структурой, например для поиска и рефакторинга (на их основе делают ide)
    Ответ написан
    Комментировать