Лекция 13 (лекции (2002))

2019-09-19СтудИзба

Описание файла

Файл "Лекция 13" внутри архива находится в папке "лекции (2002)". Документ из архива "лекции (2002)", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Онлайн просмотр документа "Лекция 13"

Текст из документа "Лекция 13"

Лекция 13

Как же копировать объекты? Почему нужен конструктор копирования в С++ (он и операция присваивания в С++ могут перекрываться)? Вот случаи, когда работает конструктор копирования:

X x = y;

void f(X x); - передача по значению

X f() {return x;}

a = b; - операция присваивания (реальное копирование объектов)

В ссылочных ЯП (Delphi, C#, Java) копирования объектов не происходит, а только копирование ссылок. И в выражении X x = y; «x»- это место для ссылки на объект класса X. Толко при операторе присваивания (a = b) нет инициализации , в отличие от остальных случаев, где работает конструктор копирования. Как же осуществляется глубокое копирование объекта в ЯП с ссылочной семантикой (нам это необходимо, когда мы передаём объект по значению и хотим поменять какое-то состояние этого объекта, а первоначальный объект трогать не хотим. В Delphi, Java и C# в теле можем реализовать специальный метод Clone (он присутствует на вершине иерархии классов и размещает точную копию объекта в оперативной памяти; в случае Delphi мы должны позаботиться, чтобы освободить потом память, а в C# и Java, где автоматическая сборка мусора, он автоматически уйдёт из памяти):

X t = x.Clone();

Он присутствует в любом классе и по умолчанию его реализация- это побитовое копрование.

В С++ надо было переопределять и конструктор копирования ( X(X&) ) и операцию присваивания.

Если хотим запретить копирование (например для обеспечения уникальности объектов):

1)Ссылочные ЯП: переопределяем метод Clone, вызываем исключение «нельзя копировать объект» (встроенное).

2)С++: определить конструктор копирования и оператор присваивания приватными

Понятие «свойства»

Подчёркивает дуализм понятия класса, и, вообще, понятия данных и операций. Свойства- это операции. В некоторых ЯП длина строки хранится явно в качестве её первого байта, она служит данным. Так же удобно в некоторых случаях предоставлять пользователю операции над типом данных в виде чтения и записи какой-то переменной. Например 4 свойства (имеют целый тип) типа данных «окно» (Window):


Window w;

w.x = 0; - на самом деле это достаточно сложная операция (протокол переговоров с вышестоящими владельцами окна, на тему может ли оно вообще имзмениться, может ли именно так, потом ещё системные вызовы на перерисовку и так далее) с точки зрения реализации, но тривиальна с точки зрения пользователя

Свойства (на языковом уровне) поддерживаются Delphi, C# и последних версиях Basic, для хорошей интеграции с интегрированной средой (как и перечислимый тип в С#).

Вообще говоря, оно задаётся таким образом:

T Prop - некое свойство

T.GetProp() {…} - возвращает значение свойства (a = w.y;)

void T.SetProp(T x) {…} - устанавливает свойство

В случае «w.x = 0;» для класса окно вызывается метод «Setx(…);». А в случае «a = w.y;» для данного окна вызывается метод «Gety(…);».

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

Редактор ресурсов в интегрированной среде:


В случае перечислимого типа справа будет комбобокс с соответсвующими значениями, а в случае целых значений- нечто типа редакторского окна.

C#:

class Window {

Int x {

Get() {…}

Set() {…}

}

};

Window w = new Window;

w.x = 1; - значит вызываем метод set

a = w.x; - значит вызываем метод get

Если хотим устанавливать переменную только на чтение: не определяем метод set- это свойство можно считывать, но нельзя записывать. И наоборот для определения только на запись.

В Delphi несколько более сложный синтаксис.. Там есть ключевое слово property:

property x: тип

Прототипы:

Read ___;

Write ___;

Где первый реализован как function():тип; а второй- procedure(x: тип);. В простейшем случае вместо этих процедур может быть указан член-данное соответствующего класса и тогда это свойство будет аналогично считыванию или записи соответствующей переменной. Причём часто в качестве Read используют значения специальных переменных класса, а в качестве Write, конечно указывают процедуру. Такой синтаксис подобен синтаксису языка C#, но тут есть ещё один наворот- после свойства мы можем ещё установить ключевое слово «:default;». Это значит:

T = class

property x: Y;

a: T; b:Y;

a.x := b;

a := b; - нет ошибки, так как «х»- умолчательное свойство

И тут вызывается неявный оператор преобразования объекта к свойству

a := b; реально подставляется a.x := b;

b := a; реально подставляется b := a.x;

Это интересное свойство. Понятие «свойства» введено исключительно для удобства программирования в интегрированной среде, к тому же компоненты удобно описывать в качестве свойств. В Java это понятие отсутствует, так как все эти свойства классов и компонент, которые удобно использовать с точки зрения интегрированных сред, лучше описывать не на самом ЯП, а на каком-то специальном языке, например, на языке описания интерфейсов. Есть ODL (Object Definition Language) и IDL (Interface Definition Language) - языки описаний интерфейсов. Для них существуют отображения в конкретные ЯП.

Инициализация объектов

Она очень мощно реализована в С++. В некоторых случаях синтаксис конструкторов не очень хорош. Например, при инициализации статических объектов, которые в C# и Java встречаются очень часто. Каким образом инициализировать статические члены?

С++:

class X {

static int x;

};

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

int X::x;

Также, при создании, мы можем проинициализировать:

int X::x = 1;

Это же касается и инициализации констант. В современном синтаксисе языка С++ их можно инициализировать непосредственно при определении. Но в данном случае у нас достаточно тривиальный объект, а что делать в случае сложных объектов? И каким образом программист может управлять инициализацией статических объектов?

class Y {…};

class X {

static Y y;

};

Где-то должно быть:

Y X::y;

Этот объект будет инициализирован до начала выполнения функции main. Как мы уже говорили, конструкторы всех статических объектов выполняются в стандартном прологе. Но инициализация одних статических членов может зависить от других. Самой простой пример- стандартные классы ввода-вывода. В С есть библиотека stdio.h, а в С++ рекомендуется использовать iostream, где есть два класса для ввода/вывода: cin и cout (аналоги stdin и stdout), и эта библиотека написана полностью на языке С++ и полностью удовлетворяет его требованиям. Конструкторы статических объектов работают до начала функции main и где гарантия, что, если один из конструкторов вызывает исключение из-за некой неприятности при инициализации и пытается что-то вывести в cout, cout уже будет открыт? Это проблема, её можно обойти, но очень сложно. Путём введения некого статического члена для класса iostream, который и говорит об инициализированности объекта, и любая операция ввода вывода должна посмотреть, а инициализирован ли класс, используя этот статический объект. Если не инициализирован, то инициализировать класс, открыть cout и только после этого выводить. Очевидный недостаток этого метода: при каждой операции ввода-вывода мы проверяем инициализированность этого класса. В общем случае в С++ это проблема, в основном связанная с механизмом независимой раздельной трансляции. В других языках это попытались исправить.

Java: статический инициализатор:

static int x = 0;

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

static {блок кода}

- где блок кода, инициализирует все статические перменные.

Например, статический массив объектов:

static int [] a;

static {a = new int[10]; for (int i = 0; i < 10; i++) a[i] = 1;}

Это очень полезная вещь, вкупе с механизмом управления загрузкой классов мы

решаем практически все проблемы.

В С# то же, но вместо статических инициализаторов- статические конструкторы (из-за политической установки быть похожим на С++, но не быть похожим на Java), хотя это тоже самое:

static X() {...}

Он выполняется только один раз, когда класс загружается в память и полностью аналогичен соответствующему статическому блоку кода.

В Delphi нет понятия статических членов, но на самом деле: статический член- это как бы глобальная переменная, локализованная внутри класса, который в данном отношении похож на модуль, который хранит внутри этот экземпляр. В Delphi существует понятие unit и мы просто внутри него заводим эту переменную (если хотим её экспортировать- объявляем её в интерфейсе), и обращаемя к ней не через имя класса (В Java и С# “X.i”, а в С++ “X::i”, а через имя модуля. Здесь глобальные переменные локализованы в рамках unit’a. Но когда они инициализируются?

unit M;

interface

x: Y;

//Обращаемся из других: M.x- похоже на статический член класса. Если //хотим сделать её не публичной, то просто надо перенести её в //implementation.

Implementation

initialization //выполняется тогда, когда модуль загружается в //память (~ конструктор статического объекта),

//тут инициализируем переменную «х»

...

finalization //выполняется тогда, когда модуль выгружается //из памяти (~ деструктор статического объекта)

end M.

В Delphi как и во всех языках с зависимой трансляцией определён порядок загрузки модулей в память и программист может им воспользоваться. Так как в Delphi нет автоматического вызова конструкторов и деструкторов, то понадобилась специальная конструкция для статических членов, то есть переменных, описанных либо в интерфейсе, либо в реализации.

Деструкторы

Деструкторы нужны только в C++ и Delphi. Деструктор- это нечто обратное конструктору, и если первый превращает кусок памяти в объект, то второй делает наоборот после него может работать менеджер динамической памяти и эту память утилизировать.

Delphi:

X.FREE

Это единственная возможность удалить объект класса из динамической памяти.

В C++ деструкторы вызываются автоматически, когда объекты уходят из памяти. В случае статических объектов: в стандартном эпилоге (после выхода из функции main) или при выходе из блока, а в случае динамических объектов при вызове метода delete.

В Java нет деструкторов, так как объекты там имеют ссылочную семантику. Объекты прекращают своё существование, когда работает сборщик мусора, а когда он работает- никто не знает. Известно только, что если количество ссылок на объект равно нулю, то сборщик мусора имеет право в любой момент удалить его из памяти, но не обязан. Хотя во всех языках с автоматической сборкой мусора (C#, Java) существует специальный системный вызов, который форсируют сборку мусора (типа flushall, который все буферыфайлов синхронизирует с диском), но им лучше не злоупотреблять, так.как он сильно тормозит работу программы. Существует специальный метод- аналог деструктора:

void finalize() {...}

Его вызовет сборщик мусора, когда объект уходит из памяти. Но мы не можем предсказать, когда этот метод будет вызван, более того, если программа кончится до того, как у нас освобождены все объекты (сборщик мусора имеет право не освобождать объекты если программа у нас всё-равно кончается), то для некоторых объектов этот метод вообще не будет вызван. Поэтому, в случае, если мы захватываем критически важные системные ресурсы, в конструкторе класса Х или во время его функционирования, то тогда использовать метод finalize не рекомендуется. Лучше использовать метод класса:

close() {...}

и, вообще говоря, вызывать его явно. В Delphi нет автоматической сборки мусора и программист должен вызывать деструкторы явно сам, освобождая ресурсы. Здесь тоже самое, но не любой класс захватывает критически важные системные ресурсы (например comport’ы, которые как правило открываются в монопольном режиме).

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

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