Задать вопрос
Ответы пользователя по тегу C++
  • Существует ли функция подсчета определенного символа в строке на С++?

    @MiiNiPaa
    Не нашли вы, потому что функция для подсчёта количества определённых символов в строке никому не нужна, когда есть функция для подсчёта количества произвольных элементов в произвольной последовательности: en.cppreference.com/w/cpp/algorithm/count
    Ответ написан
    Комментировать
  • Почему происходит пропуск функции считывания строки gets_s?

    @MiiNiPaa
    Главная проблема — смешивание форматированного и неформатированного ввода: stackoverflow.com/a/21567292/3410396

    И да, не мешайте С и С++. Используйте getline вместо gets_s
    Ответ написан
    2 комментария
  • Как работает размещающий оператор new?

    @MiiNiPaa
    Это не размещающий new. Это обычное создание объекта. Коструктор хайлайтера регистрирует себя в родительском объекте и родительский объект ответственен за его удаление, поэтому результат new-expression не используется.

    Placement new выглядит как:
    new ( <pointer> ) ClassName(...)

    Чтобы понять, как работает размещающее new, надо понять отличие new-expression от оператора new. new-expression делает вещи:
    1. Вызывает оператор new, передавая в него параметры написанные после new и до имени класса. Этот оператор выделяет память и возвращает указатель на выделенную память
    2. Вызывает конструктор класса, передав параметры написанные после имени класса. Это создаст объект в памяти выделенной в (1)


    Размещающий оператор new берёт в качестве параметра указатель на уже выделенную память и просто возвращает его.
    Ответ написан
    2 комментария
  • Где ошибка в коде на С++?

    @MiiNiPaa
    b[i]=... А чему равняется i здесь?
    Ответ написан
    Комментировать
  • Какие языки позволяет связывать с C++ компилятор gcc?

    @MiiNiPaa
    Гарантировано можно использовать extern "C". Остальное — implementation defined, смотрите документацию к компилятору.
    Ответ написан
    Комментировать
  • Что делать, если отсутствует официально постовляемый API, а возможности приложения уж очень хочется расширить?

    @MiiNiPaa
    1) Реверс-инжиниринг, чтобы понять, как код игры используется для создания игры, Затем:

    2) Dll Injection чтобы управлять процессом игры напрямую, или больше реверс-инжиниринга, чтобы воссоздать действия необходимые для создания игры в своей программе.
    Ответ написан
    2 комментария
  • Можно ли возвращать лямбды?

    @MiiNiPaa
    Вот так делать - это нормально?
    Вполне

    И что в таком случае возвращается, указатель на функцию или сама функция?
    Функциональный объект. Лямбда — не функция, она может быть приведена к указателю на функцию в некоторых случаях.

    Если возвращается указатель, то где хранится сама функция, в куче или стеке?
    «Функция» лямбды хранится там же, где и остальной код. На лету ничего не собирается и не компилируется. Лямбда это синтаксический сахар для объявления класса с перегруженым оператором вызова функции.

    И еще один вопрос, по этой же теме:
    Это сокращенная запись вот такой конструкции:
    Или что то другое?
    lambda имеет уникальный тип. Это не функция (но может быть приведена к ней в данном случае).
    Ответ написан
    Комментировать
  • Как лечить char warning overflow при считывании с файла?

    @MiiNiPaa
    Вполне возможно, что '»' на самом деле не чар, а int. Гуглите multicharacter literals. Зависит это от кодировки файла и IDE. Попробуйте сделать так и запостить резултат:

    #include <iostream>
    #include <type_traits>
    
    int main()
    {
        std::cout << typeid('»').name() << '\n';
    }
    Ответ написан
    Комментировать
  • {} при инициализаци массива массивов?

    @MiiNiPaa
    Вообще, оно не должно компилироваться вообще. Размеры массивов должны быть константными выражениями.

    То что у вас — расширение компилятора. Не работает в С++14 скорее всего потому, что в С++11 компилятор использует собственное расширение основанное на сишных VLA. А в С++14 — более ограниченные С++ ARB, которые могли войти в С++14, но не вошли.
    Ответ написан
    2 комментария
  • Как именно работает данный конструктор list?

    @MiiNiPaa
    Что является результатом данной строки

    Пустой список. Чтобы там что-либо было, туда нужно что-нибудь положить

    И как производить обращение к элементам, в таком случае?

    К первому/последнему — через front/back. К остальным — через итераторы.

    Пример:
    list<vector<string>> lvs {{"Hello", "World"}, {"Goodbye", "Universe"}, {"What", "am", "I", "doing"}};
    for(auto it = list.cbegin(), it != list.cend(), ++it) {//Проходимся по всем элементам списка
        cout << (*it)[1] << '\n';
        // (*it) даст элемент списка: vector<string>
        // Пы можем обратиться к элементу вектора при помощи оператора []
    }
    Ответ написан
    3 комментария
  • Как работает static cast?

    @MiiNiPaa
    Пытается произвести преобразование используя определённые операторы преобразования и конструкторы. Если подобного преобразования нет, выдаст ошибку.

    С указателями на классы связанные отношением наследования всё несколько сложнее:

    1) Преобразование указателя на дочерний класс в указатель на базовый.
    static_cast безопасно приводит типы: возвращаемое значение — указатель на базовый субобъект дочернего класса.

    2) Преобразование указателя на базовый класс в указатель на дочерний.
    Преобразование всегда успешно (нет ошибки компиляции). Если базовый указатель указывает на субобъект дочернего класса, приведение успешно и безопасно. Если базовый указатель не указывает на субобъект дочернего класса, то результат приведения не определён и может случится что угодно.
    struct base 
    {};
    struct derived: base
    {};
    //...
    derived* d = new derived;
    
    //Работает, безопасно
    base* b = static_cast<base*>(d);
    
    //Работает, безопасно так как b на самом деле указывает на derived
    d = static_cast<derived*>(b);
    
    b = new base;
    //Undefined Behavior. Программа превращается в тыкву.
    d = static_cast<derived*>(b);
    Ответ написан
    4 комментария
  • Замена в строке одного символа на другой, как сделать на Си?

    @MiiNiPaa
    Основная проблема в том, что ваши массивы под строки символов замены размером в 1 чар. А писаться будет как минимум 2: введённый символ и символ конца строки.
    Ответ написан
  • Где найти библиотеку?

    @MiiNiPaa
    Она является частью языка. Если компилятор ругается не её отсутствие: выкиньте Turbo C++/установите компилятор по-нормальному.
    Ответ написан
  • Где ошибка в коде на С++?

    @MiiNiPaa
    В введённых значениях. Посчитайте ручками. Вы берёте корень от отрицательного числа.
    Ответ написан
    Комментировать
  • По какому принципу выводятся числа (back_inserter, front_inserter)?

    @MiiNiPaa
    Вы перепутали что при чём выводится. У back_inserter будет 7 8 9 1 2 3, у front_inserter — 3 2 1 7 8 9

    back_inserter вставляет каждый элемент в конец: 7 8 9 → 7 8 9 1 → 7 8 9 1 2 → 7 8 9 1 2 3

    front_inserter — в начало: 7 8 9 → 1 7 8 9 → 2 1 7 8 9 → 3 2 1 7 8 9
    Ответ написан
  • Как заставить сработать исключение std::bad_alloc?

    @MiiNiPaa
    Я напишу ответы на вопросы в комментариях здесь:

    А system("pause") платформонезависимый?
    Нет
    Ведь программа сразу же закрывается. Или како-то это по другому решается?
    Настройте IDE нормально, либо запускайте программы из командной строки, а не двойным щелчком. Это нормальное и правильное поведение для консольных программ.
    Ссылка используется только в случае с std::bad_alloc или с классами тоже?
    Стандарт обработки исключений в С++: бросать по значению, ловить по ссылке.
    То есть, такого типа указатели нужно всегда инициализировать? Если не char* ptr = new char[SIZE], то char* ptr = NULL и на другой строке ptr = new char[SIZE]?
    Если char* ptr = new char[SIZE] бросит исключение, то переменной ptr не существует и удалять нечего. Нужно всегда инициализировать переменную при объявлении. Чем — другой вопрос.

    И да, на современных системах единственный гарантированный способ получить bad_alloc — истощить адресное пространство программы. И убедится, что компилятор не выкинет выделение памяти как ненужное. Проще кинуть bad_alloc самомтоятельно.
    Ответ написан
    Комментировать
  • Как использовать dynamic_cast?

    @MiiNiPaa
    Чтобы безопасно скастовать базовый класс к дочернему.

    Допустим у вас есть указатель Base* foo, который скорее всего указывает на производный класс. И вы хотите скастовать его к производному, чтобы использовать его функции. Но есть шанс, что это не производный класс в таком случае у вас будут проблемы.

    Чтобы избежать проблем можно использовать dynamic_cast(foo). Каст вернёт nullptr в случае, если указатель не указывает на Derived класс.
    Ответ написан
    Комментировать
  • Указатель на указатель?

    @MiiNiPaa
    В современном С++ вообще указателей стараются избегать. Но вот несколько примеров:

    Псевдо2D массив — массив массивов

    Массив указателей. Например вектор хранит внутри указатель на буфер. .data() возвращает этот указатель. Если там хранятся указатели, получается указатель на указатель.

    Когда нужно изменить указатель и используется АПИ С: указатель на объект используется если нужно изменить объект так, чтобы ето было видно вне изменяющей функции. В данном случае объект — другой указатель.
    Ответ написан
    2 комментария
  • Почему нельзя объявлять стековые объекты внешних классов для внутренних классов?

    @MiiNiPaa
    Класс считается complete когда при его парсинге достинается закрывающая скобка. При объявлении вложенного класса внутри внешнего, он ещё не полон и объявить член его типа нельзя. Указатель на неполный тип создавать можно, поэтому первый вариант компилируется.

    Поправить можно так:

    struct Outer 
    {
      struct Inner;
    };
    
    struct Outer::Inner 
    {
        Outer _outer;
        Inner() : _outer() { }
    };
    Ответ написан
    1 комментарий