Бьерн Страуструп. Язык программирования С++ Второе дополненное издание


 Поддержка объектно-ориентированного программирования



Pdf көрінісі
бет42/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   38   39   40   41   42   43   44   45   ...   256
Байланысты:
Бьерн Страуструп. Язык программирования С . М Бином, 2011

1.5 Поддержка объектно-ориентированного программирования 
Поддержку объектно-ориентированного программирования обеспечивают классы вместе с механизмом 
наследования, а также механизм вызова функций-членов в зависимости от истинного типа объекта 
(дело в том, что возможны случаи, когда этот тип неизвестен на стадии трансляции). Особенно важную 
роль играет механизм вызова функций-членов. Не менее важны средства, поддерживающие 
абстракцию данных (о них мы говорили ранее). Все доводы в пользу абстракции данных и 
базирующихся на ней методов, которые позволяют естественно и красиво работать с типами, 
действуют и для языка, поддерживающего объектно-ориентированное программирование. Успех обоих 
методов зависит от способа построения типов, от того, насколько они просты, гибки и эффективны. 
Метод объектно-ориентированного программирования позволяет определять более общие и гибкие 
пользовательские типы по сравнению с теми, которые получаются, если использовать только 
абстракцию данных. 
1.5.1 Механизм вызова 
Основное средство поддержки объектно-ориентированного программирования - это механизм вызова 
функции-члена для данного объекта, когда истинный тип его на стадии трансляции неизвестен. Пусть, 
например, есть указатель p. Как происходит вызов p->rotate(45)? Поскольку С++ базируется на 
статическом контроле типов, задающее вызов выражение имеет смысл только при условии, что 
функция rotate() уже была описана. Далее, из обозначения p->rotate() мы видим, что p является 
указателем на объект некоторого класса, а rotate должна быть членом этого класса. Как и при всяком 
статическом контроле типов проверка корректности вызова нужна для того, чтобы убедиться (насколько 
это возможно на стадии трансляции), что типы в программе используются непротиворечивым образом. 
Тем самым гарантируется, что программа свободна от многих видов ошибок. 
Итак, транслятору должно быть известно описание класса, аналогичное тем, что приводились в $$1.2.5: 
class shape 

// 
... 
public: 
// 
... 
virtual void rotate ( int ); 
// 
... 
}; 
а указатель p должен быть описан, например, так: 


Бьерн Страуструп.
Язык программирования С++ 
 
41 
T * p; 
где T - класс shape или производный от него класс. Тогда транслятор видит, что класс объекта, на 
который настроен указатель p, действительно имеет функцию rotate(), а функция имеет параметр типа 
int. Значит, p->rotate(45) корректное выражение. 
Поскольку shape::rotate() была описана как виртуальная функция, нужно использовать механизм вызова 
виртуальной функции. Чтобы узнать, какую именно из функций rotate следует вызвать, нужно до вызова 
получить из объекта некоторую служебную информацию, которая была помещена туда при его 
создании. Как только установлено, какую функцию надо вызвать, допустим circle::rotate, происходит ее 
вызов с уже упоминавшимся контролем типа. Обычно в качестве служебной информации используется 
таблица адресов функций, а транслятор преобразует имя rotate в индекс этой таблицы. С учетом этой 
таблицы объект типа shape можно представить так: 
center 
vtbl: 
color &X::draw 
&Y::rotate 
... 
... 
Функции из таблицы виртуальных функций vtbl позволяют правильно работать с объектом даже в тех 
случаях, когда в вызывающей функции неизвестны ни таблица vtbl, ни расположение данных в части 
объекта, обозначенной ... . Здесь как X и Y обозначены имена классов, в которые входят вызываемые 
функции. Для объекта circle оба имени X и Y есть circle. Вызов виртуальной функции может быть по сути 
столь же эффективен, как вызов обычной функции. 


Достарыңызбен бөлісу:
1   ...   38   39   40   41   42   43   44   45   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет