Язык программирования C++. Вводный курс


Доступ к членам базового класса - часть 5


Рассмотрим инициализацию указателя на базовый Query адресом объекта производного NameQuery:

Query *pb = new NameQuery( "sprite" );

При вызове виртуальной функции, определенной в базовом классе Query, например:

pb->eval();  // вызывается NameQuery::eval()

вызывается функция из NameQuery. За исключением вызова виртуальной функции, объявленной в Query и переопределенной в NameQuery, другого способа напрямую добраться до членов класса NameQuery

через указатель pb не существует:

(a)               если в Query и NameQuery

объявлены некоторые невиртуальные функции-члены с одинаковым именем, то через pb

всегда вызывается экземпляр из Query;

(b)               если в Query и NameQuery

объявлены одноименные члены, то через pb обращение происходит к члену класса Query;

(c)                если в NameQuery

имеется виртуальная функция, отсутствующая в Query, скажем suffix(), то попытка вызвать ее через pb приводит к ошибке компиляции:

// ошибка: suffix() - не член класса Query

pb->suffix();

·                  Обращение к члену или невиртуальной функции-члену класса NameQuery

через pb

тоже вызывает ошибку компиляции:

// ошибка: _name - не член класса Query

pb->_name;

Квалификация имени члена в этом случае не помогает:

// ошибка: у класса Query нет базового класса NameQuery

pb->NameQuery::_name;

В C++ с помощью указателя на базовый класс можно работать только с данными и функциями-членами, включая виртуальные, которые объявлены (или унаследованы) в самом этом классе, независимо от того, какой фактический объект адресуется указателем. Объявление функции-члена виртуальной откладывает решение вопроса о том, какой экземпляр функции вызвать, до выяснения (во время выполнения программы) фактического типа объекта, адресуемого pb.




Начало  Назад  Вперед