Читаем С++ для "чайников" . полностью

Вызов VehicleFn( с ) допустим, поскольку с ЯВЛЯЕТСЯ Vehicle. Вызов motorFn( с ) недопустим, поскольку с — не Motor, хотя он и содержит Motor. Если возникает необходимость передать функции только ту часть с, которая является мотором, это следует выразить явно: motorFn( с.motor ).

_________________

239 стр. Глава 20. Наследование классов

<subtitle id="chapter21"><emphasis>Глава 21. ЗНАКОМСТВО С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ-ЧЛЕНАМИ: НАСТОЯЩИЕ ЛИ ОНИ...240</emphasis></subtitle>

ОГЛАВЛЕНИЕ

        В этой главе...

►Зачем нужен полиморфизм 243

►Как работает полиморфизм 245

►Когда функция не является виртуальной 246

►Виртуальные особенности 247

Количество и тип аргументов функции включены в её полное или, другими словами, расширенное имя. Это позволяет создавать в одной программе функции с одним и тем же именем ( если различаются их полные имена ):

    void someFn( int )

    void someFn( char* )

    void someFn( char* , double )

Во всех трёх случаях функции имеют одинаковое короткое имя someFn( ). Полные имена всех трёх функций различаются: someFn( int ) отличается от someFn( char* ) и т.д. С++ решает, какую именно функцию нужно вызвать, рассматривая полные имена слева направо.

«Тип возвращаемого значения не является частью полного имени функции, поэтому вы не можете иметь две функции с одинаковым расширенным именем, отличающиеся только типом возвращаемого объекта.»

[Атас!]

Итак, функции-члены могут быть перегружены. При этом помимо количества и типов аргументов расширенное имя функции-члена содержит ещё и имя класса.

С появлением наследования возникает небольшая неувязка. Что, если функция-член базового класса имеет то же имя, что и функция-член подкласса? Попробуем разобраться с простым фрагментом кода:

    class Student

    {

    public :

        float calcTuition( ) ;

    } ;

    class GraduateStudent : public Student

    {

    public :

        float calcTuition( ) ;

    } ;

    int main( int argcs , char* pArgs[ ] )

    {

        Student s ;

        GraduateStudent gs ;

        s.calcTuition( ) ; /* Вызывает Student::calcTuition( ) */

        gs.calcTuition( ) ; /* Вызывает  GraduateStudent::calcTuition( ) */

        return 0 ;

    }

_________________

240 стр. Часть 4. Наследование

Как и в любой ситуации с перегрузкой, когда программист обращается к calcTuition( ), С++ должен решить, какая именно функция calcTuition( ) вызывается. Если две функции отличаются типами аргументов, то нет никаких проблем. Даже если аргументы одинаковы, различий в именах класса достаточно, чтобы решить, какой именно вызов нужно осуществить, а значит, в этом примере нет ничего необычного. Вызов s.calcTuition( ) обращается к Student::calcTuition( ), поскольку s локально объявлена как Student, тогда как gs.calcTuition( ) обращается к GraduateStudent::calcTuition( ).

Но что, если класс объекта не может быть точно определён на этапе компиляции? Чтобы продемонстрировать подобную ситуацию, нужно просто немного изменить приведённую выше программу:

    //

    /* OverloadOverride — демонстрация невозможности  */

    /*                    точного определения типа */

    //

    #include

    #include

    #include

    using namespace std ;

    class Student

    {

      public :

        /* Раскомментируйте одну из двух следующих строк; одна выполняет раннее связывание calcTuition( ), а вторая — позднее  */

        float calcTuition( )

        /* virtual float calcTuition( ) */

        {

            cout << "Функция Student::calcTuition" << endl ;

            return 0 ;

        }

    } ;

    class GraduateStudent : public Student

    {

      public :

        float calcTuition( )

        {

            cout << "Функция GraduateStudent::calcTuition"

                 << endl ;

            return 0 ;

        }

    } ;

    void fn( Student& x )

    {

Перейти на страницу:

Все книги серии Для чайников

Похожие книги

Разработка приложений в среде Linux. Второе издание
Разработка приложений в среде Linux. Второе издание

Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет СЃРѕР±РѕР№ отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из РґСЂСѓРіРёС… операционных систем. РџРѕРґСЂРѕР±но рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование СЃРІРѕР±одно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Р

Майкл К. Джонсон , Эрик В. Троан

Программирование, программы, базы данных
Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript
Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript

Данная книга посвящена программированию игр с помощью ActionScript. Здесь вы найдете подробные указания, необходимые для создания самых разных игр – аркад, головоломок, загадок и даже игровых автоматов. В тексте приведены исходные коды программ и детальные, доступно изложенные инструкции. Базовые принципы программирования ActionScript рассматриваются на примере игр, однако вы без труда сможете применить полученные знания и для разработки неигровых проектов, таких как Web-дизайн и реклама. Рекомендации Гэри Розенцвейга помогут вам не только придумывать занимательные игры и размещать их на Web-сайте, но и оптимизировать скорость их работы, а также защищать свои творения от несанкционированного копирования. Представленный в книге код несложно изменить для использования в других программах.Книга предназначена для широкого круга читателей – создателей анимационных роликов, художников-оформителей, программистов и разработчиков Web-сайтов. Издание может также выступать в качестве практического пособия по изучению ActionScript.

Гэри Розенцвейг

Программирование, программы, базы данных / Программирование / Книги по IT
Язык программирования Euphoria. Справочное руководство
Язык программирования Euphoria. Справочное руководство

Euphoria (юфо'ри, также рус. эйфори'я, ра'дость) — язык программирования, созданный Робертом Крейгом (Rapid Deployment Software) в Канаде, Торонто. Название Euphoria — это акроним для «End-User Programming with Hierarchical Objects for Robust Interpreted Applications».Euphoria — интерпретируемый императивный язык высокого уровня общего назначения. C помощью транслятора из исходного кода на Euphoria может быть сгенерирован исходный код на языке Си, который в свою очередь может быть скомпилирован в исполнияемый файл или динамическую библиотеку при помощи таких компиляторов, как GCC, OpenWatcom и др. Программа Euphoria также может быть «связана» с интерпретатором для получения самостоятельного исполняемого файла. Поддерживается несколько GUI-библиотек, включая Win32lib и оберток для wxWidgets, GTK+ и IUP. Euphoria имеет встроенную простую систему баз данных и обертки для работы с другими типам баз данных.[Материал из Википедии]

Коллектив авторов

Программирование, программы, базы данных