Лекции (1129116), страница 16

Файл №1129116 Лекции (Лекции) 16 страницаЛекции (1129116) страница 162019-05-11СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 16)

Пролог – здесь инициализируются статические объекты

Main - выполнение программы (плюс создание/уничтожение динамических объектов)

Эпилог - уничтожение статических объектов

Для квазистатических объектов конструкторы выполняются при входе в блок, деструкторы – при выходе. Для динамических – конструкторы вызываются при вызове new, деструкторы – delete.

Для класса Complex имеет смысл писать конструкторы (причем не один), а вот деструктор – не имеет, так как класс Complex никаких ресурсов не захватывает.

Для класса же MyString деструктор писать надо - он будет удалять строку из динамической памяти, точно также для класса Stack.

В принципе, деструкторов может быть много, хотя сложно придумать параметрический деструктор (но возможность такая есть). Как правило существует деструктор умолчания. Также как и у конструктора, деструктор имеет две семантики: стандартная и пользовательская. Но у дестркутора в начале будет вызвана пользовательская деструкция (то что прописано в теле деструктора пользователем), затем деструкторы подобъектов и деструкторы базовых классов (деструкторы, описанные в родительских классах). То есть строим мы с фундамента до крыши, а ломаем, соответственно, с крыши до фундамента.

Это и есть деструкторы умолчания, они вызываются неявно. В 99% случаев их бывает достаточно. Деструкторы можно вызывать явно, но редко это бывает нужно (в отличие от конструкторов), так как явный вызов деструктора может означать только то, что мы хотим разрушить объект, а потом сразу на его месте создать новый.

Таким образом мы практически закончили раздел специальных функций. Мы не затронули функции new и delete. Но это тема для самостоятельного изучения. Напоследок стоит сказать, как можно вызывать конкретные функции классов:

имя класса :: имя функции

если функция глобальная, и для нее класс не определен, то ее вызывают:

:: имя функции

То есть, написав:

:: new

мы укажем на базовую функцию new, которую можно, например, переопределить.

Посмотрим, что же у нас получилось из концепции классов C++. А то, что фактически ничего в базисе C++ по отношению к C не прибавилось (кроме ссылочного типа), даже не был введен популярный в других языках строковый тип. Почему нет? Мы определили – потому что с помощью концепции классов можно получить тип string, гораздо более мощный, чем если бы мы ввели его в базис.

Заметим, что ни Java, ни в Delphi нельзя создать класс, аналогичный sstring, так как в этих языках нельзя, например, перекрыть операцию «+». Поэтому в Delphi появился встроенный тип string и почти то же самое было сделано в Java (в Java не разрешено перекрывать стандартные операции). Например, в Java можно написать:

S+5;

и число 5 будет переведено в строку «5», так как в Java есть функция ToString для всех объектов.

Это единственный выход, если не делать таких же средств развития, как в C++, а эти средства иногда «кусаются», так как черезчур мощны.

Но в то же время заметим, что и в Java и в C++ отсутствует понятие диапазона. Иногда оно полезно, иногда нет (это понятие есть в Pascal, Modula-2, Ada). Можем ли мы придумать какой-нибудь класс, полностью эквивалентный диапазону? Конечно, да.

class Diap {

int L,R;

int Val

Diap( int l, int r) {L=l; R=r;};

operator int () {return Val;)

int operator = (int v) { if (v<L) || (v>R) Error(); Val=v; return Val;}

};

В чем недостаток? В том, что нам приходится хранить L и R для каждого вновь создаваемого объекта. Что нужно для исправления этого недостатка? Можно объявить их статически (в этом случае придется создавать для каждого диапазона свой класс).

Приведем в пример класс Vector:

class Vector {

int *body

int size;

explicit Vector (int)

~Vector() {delete [ ] body; }

( После delete мы пишем квадратные скобки по следующей причине, если есть:

p = new X[10];

то для каждого из 11 объектов будет вызван конструктор умолчания. Когда мы делаем

delete [ ] p;

это говорит о том, что надо вызывать деструктор для каждого элемента массива. Если скобки не указать, то деструктор будет вызван только для первого объекта.)

int& operator [ ] (int i) { if (i<0 || i>size) Error();

return a[i];

}

Это примерно то же самое, что делает компилятор, например, Ada.

Лекция 13

Несмотря на то, что в языке С++ появились принципиально новые возможности, они, кроме преимуществ, влекут за собой и проблемы. Основная проблема – возросшая сложность языка. Интересно посмотреть, как языки, похожие на С++, борются с этой проблемой. Речь идет, прежде всего, о языках Java и Delphi (Delphi – это не язык, а система визуального программирования, использующая язык Borland Pascal with Objects, однако для краткости будем называть этот язык Delphi).

Java.

У языка Java есть ряд преимуществ по сравнению с С++ и Delphi, потому что, при создании, этот язык не был связан рамками совместимости с другими языками. Создатели этого языка взяли из С++ только то, что им показалось удобным, все что им показалось не удобным, они вынесли за скобки. Естественно, Java - классово-ориентированный язык, второй плюс языка Java – это наследование. Объектно-ориентированность пронизывает этот язык сверху до низу, в отличие от С++ и Delphi, которые связаны с понятием совместимости.

Структура Java стала более стройной и жесткой. В Java есть только понятие класса, причем создатели отделили понятие физического модуля от логического. В С++ физический модуль – это просто файл – совершенно не структурированная вещь. Все, что есть в языке Java, – это все относится к классам. Т.е. отсутствует понятие глобальных переменных и функций, переменные и функции могут быть только членами класса. Все что мы делаем в языке Java, – это описываем классы. В классах могут быть члены, в том числе статические, но никаких глобальных объектов быть не может.

В Java есть несколько встроенных классов, и прежде всего, класс Object. Все классы являются наследниками класса Object. Кроме того, если мы говорим об исполняемой программе на языке Java, то должно быть некоторое "яйцо" из которого эта программа рождается (в С++ это функция main). В некотором классе обязательно должна быть описана статическая функция main:

public static void main (String[] args);

Понятие статических членов в Java такое же как в С++, и это единственный способ сделать объекты глобальными по смыслу. Аргументом функции main является набор строк-параметров программы, первая строка содержит имя программы. Количество параметров определяется через функцию-атрибут класса String. Виртуальная машина языка Java начинает выполнение программы с функции main.

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

class X {

static int x;

};

int X::x = 1;

В отличие от С++, Java не поддерживает принцип РОРИ (Разделение Определения, Реализации, Использования). Однако, как и во всех языках, в Java определение и реализация отделяется от использования. В языках Модула-2 и Ада определение отделено от реализации, в языке Оберон наоборот – определение совмещено с реализацией. В языках с разделенными определением и реализацией, после изменения реализации не требуется перекомпилировать определение. Если определение и реализация объединены, то изменения в реализации требуют перекомпиляции и определения. Однако, сейчас перекомпиляция уже не так долго выполняется, и современные языки (Java, Оберон) используют подход, объединяющий определение и реализацию. Вывод интерфейса соответствующего класса без реализации осуществляет среда программирования.

В Java также присутствует понятие конструктора. Есть безаргументные конструкторы (в С++ это конструкторы по умолчанию) и конструкторы с аргументами. Однако, семантика конструкторов упрощена. В конструкторах нет системной части. Если конструктор вызывает конструкторы базовых классов, то он должен вызывать именно безаргументные конструкторы, иначе компилятор выдаст сообщение об ошибке. Что делать, когда нужно вызывать конструкторы базовых классов с каким-то списком параметров? Для этого существует специальное ключевое слово super, которое означает ссылку на базовый класс (через super(<список параметров>) мы можем вызывать нужные конструкторы). Если компилятор находит слово super в первой стороке, то он выполняет соответствующий конструктор, иначе он пытается вставить вызов безаргументного конструктора, и если его нет, то выдает сообщение об ошибке. Такая схема несколько упрощает синтаксис.

В языке С++ был специальный синтаксис для вызова конструктора подобъектов, и по умолчанию вызывался конструктор умолчания (если его нет – ошибка). Какой подход в Java? Во-первых, в Java можно инициализировать в описании класса значения по умолчанию:

class X {

static int x=1; //инициализация переменной

Y y = new y(…); // инициализация подобъекта

int[] a = new int[3]; //Это только отведение памяти!

//Нетривиальную инициализацию можно

//произвести в конструкторе

int b[] = {1,2,3}; //Это тривиальная инициализация!

};

Конструктор в Java не будет автоматически инициализировать подобъекты, значительно будет проще, если программист сам явно вызовет конструктор объекта. Неявно компилятор может только вставить вызовы конструкторов базовых классов, потому что программист не всегда знает иерархию классов.

В Java фактически есть только два типа конструкторов – без аргументов и с аргументами. Особая роль безаргументного конструктора заключается только в том, что компилятор вставляет их в конструкторах подобъектов, если первым в конструкторе подобъекта не стоит вызов super(…). У других конструкторов вообще нет особой роли.

В Java неявные преобразования запрещены (поэтому и нет конструкторов преобразования), вспомним, что язык Java предназначен для программирования для среды Internet, а это ужесточает требования переносимости и безопасности. Язык С++ в некотором смысле, более мощный, чем Java. С++ можно расширить практически любым классом, и этот класс интегрируется с языком очень мягко. Программа на Фортране легко переводилась в С++, но на Java эту программу перевести уже не так легко.

Также отсутствует конструктор копирования. Конструктор копирования очень полезен, но только вместе с перекрытием операции присваивания. В Java запрещено перекрытие знаков стандартных операций вообще. Как же решена проблема копирования объектов? Наличие специального класса конструкторов и возможности переопределения заменены некоторым набором функций, который позволяет клонировать объекты. Операция присваивания в Java означает побитовое копирование, как для простых, так и для сложных объектов. Если один массив присваивается другому, то в результате, оба массива будут иметь одно тело (проблема висячих ссылок не возникает, потому что есть динамическая сборка мусора). Программист должен помнить, что присваивание сложных объектов – это только переброска ссылок.

Для копирования объектов используется метод класса Object, который называется clone(). Если мы хотим в массив А скопировать массив В, то мы должны писать A=B.clone(). Но по умолчанию функция clone() осуществляет побитовое копирование. Для глубокого копирования нужно переопределить эту функцию. Основные цели, которых достиг Страуструп, введя в язык С++ механизмы копирования и преобразования, были также достигнуты и создателями языка Java.

В языке Java отсутствует понятие деструктора, опять же, из-за динамической сборки мусора. О точке уничтожения объекта программист ничего не знает, потому что сборщик мусора может держать уже не нужный объект в динамической памяти до некоторого момента, по крайней мере, до переполнения. Хотя есть некоторый способ заставить сборщик мусора собрать мусор немедленно. Но нельзя сводить проблему деструкции только к выделению и освобождению динамической памяти. Как быть с захватом файлов и других системных ресурсов? Автоматическое освобождение этих ресурсов ни один компилятор обеспечить не может.

Для того, чтобы выполнять более нетривиальные действия по освобождению системных ресурсов предусмотрен метод void finalize(), который несколько похож на деструктор. Этот метод вызывается тогда, когда объект заканчивает свое существование, а конец существования объекта зависит от сборщика мусора, и предсказать этот момент нельзя. Неопределенность этого метода – это плата за динамическую сборку мусора. Если вы понаоткрывали файлов в некотором объекте, и прекращаете работу с объектом, то сборщик мусора может рассуждать так: свободной памяти много, и с удалением объектов можно подождать. При этом может переполнится таблица индексных дескрипторов открытых файлов. Еще одно отличие от деструктора – отсутствие системной части, т.е. в методе finalize() нужно обязательно вставлять метод super.finalize().

Delphi.

Язык Delphi развивался эволюционно и является несколько эклектичным. Ближним предком этого языка является Turbo Pascal. Все больше и больше язык Delphi начинает напоминать такой язык, как Java, оставаясь, при этом, компилируемым языком, сохраняя некоторую преемственность с Turbo Pascal. Интересно, что в языке Delphi появилось ключевое слово class, которое примерно соответствует ключевому слову object в Turbo Pascal. Класс в языке Delphi похож на класс Java, т.е. это всегда ссылка, и все классы являются наследниками одного класса TObject.

После определения объекта класса необходимо этот объект инициализировать. В классе TObject есть конструктор Create(…), который отводит память под объект и заполняет объект нулями. Этот конструктор надо вызывать явно. Если требуется более нетривиальная инициализация, то в классе можно определить свой конструктор, который затем и вызвать.

type T = class

Характеристики

Тип файла
Документ
Размер
1,12 Mb
Материал
Тип материала
Высшее учебное заведение

Список файлов лекций

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6274
Авторов
на СтудИзбе
316
Средний доход
с одного платного файла
Обучение Подробнее