C++ 3d.Комментарии




"Виртуальные конструкторы" - часть 2


где возвращаемый функцией указатель корректируется посредством константы delta_2, вообще говоря, не равной delta_1.

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

10.3. Виртуальные функции [class.virtual]

Тип возвращаемого значения замещающей функции может быть или идентичен типу замещаемой функции или быть ковариантным (covariant). Если функция D::f замещает функцию B::f, типы возвращаемых ими значений будут ковариантными, если они удовлетворяют следующим условиям:

    они оба являются указателями или ссылками на класс (многоуровневые указатели или ссылки на многоуровневые указатели запрещены)

    класс в возвращаемом значении B::f идентичен классу в возвращаемом значении D::f или он является однозначно определенным открытым прямым или косвенным базовым классом возвращаемого D::f класса и при этом доступен в D

    как указатели так и ссылки имеют идентичные cv-квалификаторы и, при этом, класс возвращаемого значения D::f имеет те же или меньшие cv-квалификаторы, что и класс в возвращаемом значении B::f.

    Если тип возвращаемого значения D::f отличается от типа возвращаемого значения B::f, то тип класса в возвращаемом значении D::f должен быть завершен в точке определения D::f или он должен быть типом D. Когда замещающая функция будет вызывана (как последняя заместившая функция), тип ее возвращаемого значения будет (статически) преобразован в тип возвращаемого значения замещаемой функции (5.2.2). Например: class B {}; class D : private B { friend class Derived; }; struct Base { virtual void vf1(); virtual void vf2(); virtual void vf3(); virtual B* vf4(); virtual B* vf5(); void f(); };

    struct No_good : public Base { D* vf4(); // ошибка: B (базовый класс D) недоступен };

    class A; struct Derived : public Base { void vf1(); // виртуальная и замещает Base::vf1() void vf2(int); // не виртуальная, скрывает Base::vf2() char vf3(); // ошибка: неправильный тип возвращаемого значения D* vf4(); // OK: возвращает указатель на производный класс A* vf5(); // ошибка: возвращает указатель на незавершенный класс void f(); };




    Содержание  Назад  Вперед