• В чем отличие полиморфизма от реализации интерфейса?

    Adamos
    @Adamos
    Полиморфизм - это создание дочерних классов, каждый из которых является разновидностью базового.
    Реализация интерфейса всего лишь означает, что класс умеет давать ответы на некоторый набор вопросов. При этом являться он может быть чем угодно.

    Например, класс офисной мебели может иметь подклассы - стулья и столы, каждый из которых является мебелью. При этом любой предмет в офисе должен реализовать интерфейс инвентаризации - выдавать свой инвентарный номер, чем бы он ни являлся.
    Ответ написан
    1 комментарий
  • В чем отличие полиморфизма от реализации интерфейса?

    vt4a2h
    @vt4a2h Куратор тега C++
    Senior software engineer (C++/Qt/boost)
    Тут, на самом деле, необходимо чётко определить границы.

    Есть ООП как парадигма программирования. Одна из концепций ООП называется полиморфизм. Существуют различные реализации этой концепции в языках программирования.

    В C++ есть несколько реализаций полиморфизма. Вам, на данном этапе, скорее всего интересен только полиморфизм, основанный на подтипах. Это означает, что вызывающий код может работать с набором типов из определённой иерархии, без знания о том, какой это конкретно но тип: базовый или подтип.

    Касательно интерфейсов: в C++ их нет на уровне языка, как отдельной сущности. Однако же разница между интерфейсом и абстрактным классом никуда не делась.

    Пример "обычного полиморфизма":
    // Это "интерфейс", который представляет собой набор операций, которые можно произвести над объектом
    // В данном случае, по объекту можно постучать
    class IKnockable {
    public:
        virtual ~IKnockable() = 0;
    
        // Само по себе действие: "постучать"
        virtual void knock() const = 0;
    };
    
    // Реализация интерфейса классом Door
    class Door : public IKnockable {
    public:
        // ...
        void knock() const override { std::cout << "door" << std::endl; }
        // ...
    };
    
    // Реализация интерфейса классом Window
    class Window : public IKnockable {
    public:
        // ...
        void knock() const override { std::cout << "window" << std::endl; }
        // ...
    };
    
    // ...
    
    // Какая-то функция, которая может постучать  по каждому объекту из списка, 
    // не имея представления о том, что же это за объект
    void knock(const std::vector<std::shared_ptr<IKnockable>> &knockableObjects) {
        for (auto &&knockableObject : knockableObjects) {
            knockableObject->knock();
        }
    }
    
    // ...
    
    std::vector<std::shared_ptr<IKnockable>> v = {std::make_shared<Door>(), std::make_shared<Window>()};
    knock(v); // Сначала напечатает "door", потом напечатает "window"


    Ответ на ваш изначальный вопрос: это понятия из разных областей, одно из теории типов, другое из языков программирования. Интерфейс -- это одно из средств в языках программирования, для реализации определённого типа полиморфизма.
    Ответ написан
    3 комментария
  • Какие требования для джуна на с++?

    @ksenobyte
    Хм, ну вот примерно список вопросов который мне задавали, когда я шел на ++ джуна.

    //функция, использует класс для кодирования строки. Спустя
    //какое-то время программа падает. Почему?
    Result encode(const char *string)
    {
      Encoder * coder = new Encoder();
      Result res = coder->encodeString(string);
      return res;
    }


    //Где-то в функции ниже ошибка. Найдите
    void printArray(int * mas)
    {
      for (int i = 0; i < sizeof(mas); i++)
      std::cout << mas[i] << " ";
    }


    Программа делает не то, что хочется.
    Необходимо найти ошибку и способ, чтобы такие ошибки можно было
    отлавливать на этапе компиляции.

    struct A {
      virtual std::ostream &put(std::ostream &o) const {
      return o << 'A';
      }
    };
    struct B : A {
      virtual std::ostream &put(std::ostream &o) const {
      return o << 'B';
      }
    };
    std::ostream &operator<<(std::ostream &o, const A a)
    {
      return a.put(o);
    }
    int main() {
      B b;
      std::cout << b;
    }


    Напишите программу для поиска простых чисел.
    Что такое умный указатель, какие бывают?
    Что такое виртуальные функции, что такое pure виртуальные функции.
    Тебе надо поработать с в двоичным числом, как ты это сделаешь?В чем будешь хранить?
    Классический вопрос про ООП что это, как работает, зачем? Как, три принципа и т.д.
    Больше честно говоря ничего такого не вспомню.
    Ответ написан
    Комментировать
  • Какие требования для джуна на с++?

    tsarevfs
    @tsarevfs Куратор тега C++
    C++ developer
    Зависит от компании. От джуна адекватные компании не ждут ничего конкретного. Нужно иметь минимальную базу и как-то продемонстрировать то что вы готовы учиться.
    С C++ нужно понимать основные механники:
    1. ООП. На 90% собеседований вас спросят что такое полиморфизм. Погоняют по виртуальным и не виртуальным функциям. Нужно хорошо разобраться зачем нужны конструкторы и деструкторы. Когда они вызываются. Как передаются параметры в функции. Почему что-то пишут в .h а что-то в .cpp. STL, смарт пойнтеры Итд.
    Хороший список книг:
    https://tproger.ru/books/cpp-books-middle/
    Не ожидается что в прочитаете все, но открытый на средине Майерс не должен вызывать изумления от синтаксиса в большинстве случаев.
    2. Алгоритмы. Что такое сложность в big O нотации (не обязательно дословно). Устройство и сложность основных операций для vector, list, set, map, unordered_set, unordered_map. Уметь отвечать на вопрос "Что быстрее vector или list"
    "Hacking the code interview" содержит очень краткое описание для этой части (есть перевод). Вся книга скорее на middle уровень, но почитать полезно.
    3. Иметь репозиторий даже с учебными задачами очень полезно. Я всегда смотрел код, если он был.
    4. Дальше уже специфика компании. Могут спрашивать математику, сети, Qt, ML... Тут уже смотрите что вам интереснее.
    Ответ написан
    1 комментарий
  • Какие требования для джуна на с++?

    vt4a2h
    @vt4a2h Куратор тега C++
    Senior software engineer (C++/Qt/boost)
    Заходите на сайты с вакансиями, например hh.ru и смотрите по требованиям. Можете ещё хабр почитать, там есть статьи, которые описывают опыт трудоустройства именно джунов на C++.

    Стоит отметить, что начинающий программист -- это не новичок. Это специалист с опытом работы от года и/или релевантным опытом в разработке ПО, полученном, допустим в разработке своих проектов или проектов с открытым исходным кодом.

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

    А так, можете написать что-то уровня fizzbuzz или binary search, понимаете O(n), знаете, что такое size и capacity у std::vector и зачем это надо, слышали про cache line краем уха, понимаете чем отличаются map и unordered_map, у вас есть парочка своих проектов на гитхабе и вы немного использовали ООП (кстати, ООП -- это не только про классы)... Смело можете пробовать. По крайней мере, я бы с большой вероятностью принял бы на работу такого джуна.
    Ответ написан
    3 комментария
  • Как можно вычислить максимальное и минимальное значение массива?

    BacCM
    @BacCM
    C++ почти с рождения
    Самое правильное, так:

    cout << *min_element(begin(c), end(c)) << endl;
    cout << *max_element(begin(c), end(c)) << endl;


    Можно так

    std::partial_sort(begin(с), begin(с) + 1, end(с));
    auto m = с.front();
    std::partial_sort(begin(с), begin(с) + 1, end(с), greater<long>());
    auto M = с.front();
    Ответ написан
    3 комментария
  • Как можно вычислить максимальное и минимальное значение массива?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    Коротко, ты можешь не сохранять минимальное и максимальное значение отдельно, т.к. они всегда доступны по индексу в массиве. Другое дело - это что у тебя нет этих индексов до начала прохода по массиву, тебе их просто неоткуда взять. Этот момент и определяет верное начальное состояние в решении твоей задачи. Отсутствие этого момента и приводит к тому, что твой код сейчас работает неверно.

    Тебе нужны только индексы тех элементов, которые ты считаешь как минимальный и максимальный.
    size_t min_value_index = 0;
    size_t max_value_index = 0;

    Я выбираю инициализацию в 0 для того чтобы изначально обозначить первый же элемент массива и как минимальный, и как максимальный одновременно. Именно так я определю начальное состояние алгоритма.

    Далее надо сделать проход по массиву.
    for( size_t index = 1; index < stream_length; ++index )
    {
       // ...
    }

    Мне незачем сравнивать элемент по нулевому индексу с самим собой, т.к. я изначально уже выбрал его, поэтому проход по массиву можно начать со следующего элемента.

    Теперь надо записать условие выбора минимального и максимального значений.
    for( size_t index = 1; index < stream_length; ++index )
    {
       if( stream[ index ] < stream[ min_value_index ] )
       {
          min_value_index = index;
       }
       
       if( stream[ index ] > stream[ max_value_index ] )
       {
          max_value_index = index;
       }
    }

    При записи условий очень важно соблюдать логику. Нужно писать так, чтобы выражение читалось как можно легче, используя слова в названиях и порядок записи операций.
    Тут видно что если по текущему индексу значение меньше запомненного минимального, то надо запомнить текущий индекс как индекс минимального значения. И для максимального значения точно так же.

    По завершении цикла в min_value_index будет гарантированно лежать индекс минимального значения массива, а в max_value_index - индекс максимального.

    Как работает этот код.
    Ответ написан
    7 комментариев
  • Отличие #include и using std::?

    @AltLumad
    #include - это то место откуда будут браться классы, переменные, области видимости и т.д.
    using std - это область видимости.
    Если ты не подключишь #include "vector"
    То не сможешь обратиться к std::vector;
    Ответ написан
    1 комментарий