Главная страница
Навигация по странице:

  • Наследование

  • Виртуальные методы

  • Курс ООП в С презентация. ООП в с++(полный курс). Объекты и классы


    Скачать 1.76 Mb.
    НазваниеОбъекты и классы
    АнкорКурс ООП в С презентация
    Дата21.02.2022
    Размер1.76 Mb.
    Формат файлаppt
    Имя файлаООП в с++(полный курс).ppt
    ТипДокументы
    #368655
    страница11 из 26
    1   ...   7   8   9   10   11   12   13   14   ...   26

    Наследование


    Операция присваивания не наследуется и, поэтому ее также требуется явно определить.
    Деструкторы не наследуются, и если программист не описал в производном классе деструктор, он формируется по умолчанию и вызывает деструкторы всех базовых классов.
    В отличие от конструкторов, при написании деструктора производного класса в нем не требуется явно вызывать деструкторы базовых классов, это будет сделано автоматически.
    Для иерархии классов, состоящей из нескольких уровней, деструкторы вызываются в порядке, строго обратном вызову конструкторов: сначала вызыва­ется деструктор класса, затем — деструкторы элементов класса, а потом де­структор базового класса.

    Наследование


    Теперь попробуем учесть отличия руководителя от просто работника, заключающиеся в особенности вычисления заработной платы. Метод get_salary() в таком случае должен возвращать не просто значение атрибута salary, определяющего тариф по ставке работника…
    const double employee::get_salary()
    {
    return salary;
    }
    …, а ещё и учитывать величину надбавки:
    const double manager::get_salary()
    {
    double add = 0; list::iterator i;
    for (i = Employers.begin(); i != Employers.end(); i++)
    {
    add += 0.03*(*i)->get_salary();
    }
    return salary+add;
    }

    Наследование


    Таким образом, следует вызывать нужный метод в зависимости от того, объект какого класса нам встретился в ходе работы программы. Такое поведение, называемое полиморфным, реализуется с помощью механизма виртуальных методов.
    Для того чтобы иметь возможность переопределить поведение метода get_salary() в подклассе manager, мы объявили его в классе employee как виртуальный.


    Виртуальные методы

    Виртуальные методы


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

    Виртуальные методы


    Например, мы имеем в наличии трех работников: двух подчиненных (A и B) и их руководителя C, составляющих множество E. Им назначена зарплата в 3300, 4400 и 5500 рублей соответственно. У нас стоит задача представить фактические доходы работников, которые будут определяться не только окладом.
    void main()
    {
    employee A, B; manager C;
    employee* E[3];
    E[0] = &A; E[1] = &B; E[2] = &C;
    C.Employers.push_back(&A); C.Employers.push_back(&B);
    E[0]->set_salary(3300);
    E[1]->set_salary(4400);
    E[2]->set_salary(5500);
    for (i = 0; i < 3; i++)
    {
    cout << E[i]->get_salary() << endl;
    }
    }

    Виртуальные методы


    Отметим, что во время компиляции не будет известно, на какой объект указывает E[i], следовательно, класс будет определяться по типу указателя. Соответственно будет выбран и правильный метод для вычисления заработной платы.
    В C++ реализован механизм позднего связывания, когда разрешение ссылок на метод происходит на этапе выполнения программы в зависимости от конкретного типа объекта, вызвавшего метод. Этот механизм реализован с помощью виртуальных методов и рассмотрен в следующем разделе. Для определения виртуального метода используется спецификатор virtual:
    Правила описания и использования виртуальных методов:
    Если в базовом классе метод определен как виртуальный, метод, определенный в производном классе с тем же именем и набором параметров, автоматически становится виртуальным, а с отличающимся набором параметров – обычным.
    Виртуальные методы наследуются, т.е. переопределять их в производном классе требуется только при необходимости задать отличающиеся действия. Права доступа при переопределении изменить нельзя.
    Если виртуальный метод переопределен в производном классе, объекты этого класса могут получить доступ к методу базового класса с помощью операции доступа к области видимости.
    Виртуальный метод не может объявляться с модификатором static, но может быть объявлен как дружественный.

    Виртуальные методы


    Механизм позднего связывания
    Для каждого класса (не объекта!), содержащего хотя бы один виртуальный ме­тод, компилятор создает таблицу виртуальных методов (vtbl), в которой для каждого виртуального метода записан его адрес в памяти. Адреса методов содержатся в таблице в порядке их описания в классах. Адрес любого виртуального метода имеет в vtbl одно и то же смещение для каждого класса в пределах иерархии.
    Каждый объект содержит скрытое дополнительное поле ссылки на vtbl, называемое vptr. Оно заполняется конструктором при создании объекта (для этого компилятор добавляет в начало тела конструктора соответствующие инструкции).
    На этапе компиляции ссылки на виртуальные методы заменяются на обращения к vtbl через vptr объекта, а на этапе выполнения в момент обращения к методу его адрес выбирается из таблицы. Таким образом, вызов виртуального метода, в отличие от обычных методов и функций, выполняется через дополнительный этап получения адреса метода из таблицы. Это несколько замедляет выполнение программы.

    1   ...   7   8   9   10   11   12   13   14   ...   26


    написать администратору сайта