Лекция 19 (лекции (2002)), страница 4
Описание файла
Файл "Лекция 19" внутри архива находится в папке "лекции (2002)". Документ из архива "лекции (2002)", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Онлайн просмотр документа "Лекция 19"
Текст 4 страницы из документа "Лекция 19"
Лучше всего было бы ввести какое-то ключевое слово. Но в 86-м г. Страуструп очень боялся новых ключевых слов, чтобы оказаться как можно ближе к языку С. Им был выбран такой синтаксис. От чистой виртуальной функции не требуется никакой ссылки. Абстрактный класс – это класс, в котором есть хотя бы одна чистая виртуальная функция. Компилятор следит за тем, чтобы объекты абстрактных классов не могли создаваться в программе. Т.е. мы не можем объявить
Figure C;
Но мы можем написать так
Figure * pf;
потому, что реально объект типа Figure в памяти не размещается. Но мы не имеем права писать
pf = new Figure( );
В этом месте компилятор тоже выдаст ошибку: "Инициализируется объект абстрактного класса." Мы можем писать так
pf = new Line( );
Здесь заводится объект конкретного типа. Абстрактные классы – это классы, которые нужны только как вершины в некоторой иерархии для того, чтобы из них потом вывести конкретные классы. Как правило, контейнерные процедуры обработки имеют дело с указателями или ссылками на этот базовый абстрактный класс, но с точки зрения реализации все эти указатели и ссылки указывают на объекты производных классов. Чистые виртуальные функции могут не иметь тела. Но может быть ситуация, когда чистая виртуальная функция все-таки будет вызвана. На первый взгляд это не возможно потому, что если она будет вызвана, то динамический тип соответствующего указателя должен совпадать с типом Figure. А это вроде бы не возможно потому, что статический тип Figure компилятор запрещает. Тем не менее существует случай, достаточно редкий, но не приятный, когда мы можем вызвать эту чистую виртуальную функцию.
class X{…
virtual void f( ) = 0;
X( ){… f( ); …}
}
В конструкторе класса вызывается виртуальная функция. Если бы метод не был конструктором f должна была бы вызываться исходя из динамического типа. Если внутри вызова конструктора есть вызов виртуальной функции самого объекта, компилятор всегда вставляет статический вызов (конструируется объект класса Х, и, очевидно, его тип должен совпадать с классом Х => компилятор вставит X::f( )). Выводится класс Y. В нем есть свой конструктор Y( ), который вызывает конструктор класса Х.
Поэтому на самом деле в ТВМ чистым виртуальным функциям соответствуют не нули, а стоят ссылки на некоторую функцию, типа метода Abstract из Delphi. Эта функция программируется, грубо говоря, автором компилятора. Поэтому, не смотря на то, что функция объявлена как чистая виртуальная, программист теоретически имеет право вставить ее тело, хотя вызов чистой виртуальной функции – это чаще всего ошибка.
Абстрактный класс, у которого открытым является только функциональный интерфейс, является абстрактным типом данных. Но в то же время есть примеры АТД, не являющихся абстрактным классом, и примеры абстрактных классов, не являющихся АТД.