Методы программирования 2. ООП Л. 01.
Введение в ООП. Мееров И.Б.Методы программирования
(2 семестр)
Раздел 2. Лекция 04 Конструкторы
Нижегородский государственный университет
им. Н.И. Лобачевского
Факультет вычислительной математики и кибернетики
Методы программирования
(2 семестр)
Раздел 2. Лекция 04 Конструкторы
Нижегородский государственный университет
им. Н.И. Лобачевского
Факультет вычислительной математики и кибернетики
Краткое содержание предыдущей серии
Язык C++ предоставляет средства реализации объектно-ориентированного подхода. Основа этих средств – понятие класса.
Класс является абстрактным типом данных, определяемым пользователем, и представляет собой модель реального объекта в виде данных и функций для работы с ними.
Класс = Данные + Операции
Данные = Поля. Операции = Методы.
Секции public и private служат средством разграничения доступа и скрытия деталей реализации.
Дальнейшее изучение
Сегодня мы изучим, как создаются объекты.
Итак, за дело!
Ничто так не ограничивает полёт мысли программиста, как компилятор
Объекты в оперативной памяти
Вернемся к проблеме представления объектов в оперативной памяти компьютера.
Вспомним, что нам известно?
Объекты содержат данные и ссылку на методы.
Реализация методов присутствует для класса в единственном числе.
Данные у каждого объекта свои.
Объект добирается методов своего класса при помощи ссылки.
Методы не вызываются сами по себе. Они вызываются для какого-то объекта.
Методы добираются до данных вызвавшего их объекта при помощи указателя this, который неявно передается в каждый из методов.
Создание объектов. Взгляд изнутри 1
TComplex A(), B();
A.SetRe(1); A.SetIm(2);
B.SetRe(2); B.SetIm(3);
A
Re
Im
Реализация методов
B
Re
Im
A
1
2
Реализация методов
B
2
3
ОЗУ
Создание объектов. Взгляд изнутри 2
TComplex A(), B();
A.SetRe(1); B.SetRe(2);
A
Re
Im
Реализация методов
B
Re
Im
A
1
2
Реализация методов
B
2
3
ОЗУ
void SetRe(TComplex *this, int _re);
2 способа создания объекта
Способ 1 (статически):
<Имя класса> <Имя объекта>;
TComplex C;
Способ 2 (динамически):
<Имя класса> *<Имя объекта> = new <Имя класса>();
TComplex *C1 = new TComplex();
Заметим, что () можно писать, а можно и не писать. Что это за скобки и зачем они нужны?
Можем ли мы как-то влиять на действия, происходящие при создании объектов? В частности, можем ли мы выполнить инициализацию? А если можем, то где?
Определение конструктора
Конструктор – специальный метод, который автоматически вызывается при создании объекта.
Возможные функции конструктора:
выделение памяти для полей класса;
инициализация полей начальными значениями;
создание объекта по образцу (копирование);
преобразование типа.
Синтаксис объявления конструктора
<Имя класса>(<Список параметров>);
Конструктор – специальный метод.
Имя метода совпадает с именем класса.
Конструктор не возвращает значение.
Пример:
TComplex::TComplex(int _re, int _im) {
re = _re;
im = _im;
}
Свойства конструкторов
Конструктор не возвращает значение, даже типа void. Нельзя получить указатель на конструктор.
Класс может иметь несколько конструкторов с разными параметрами для разных видов инициализации (при этом используется механизм перегрузки).
Параметры конструктора могут иметь любой тип, кроме этого же класса. Можно задавать значения параметров по умолчанию.
Конструкторы не наследуются.
Конструкторы нельзя описывать с модификаторами const, virtual и static.
Когда вызывается конструктор?
При объявлении объекта:
для статически создаваемых объектов:
TComplex A;
Если объект глобальный, конструктор вызывается до функции main!
Для динамически создаваемых объектов:
TComplex *A = new TComplex();
TComplex A = B;
При передаче параметров между функцией и вызывающей ее программой в тех случаях, когда какой-то из параметров является переменной объектного типа, и он передается по значению.
TComplex DoSomething(TComplex A) {
…
}
Виды конструкторов
Класс может иметь несколько конструкторов, позволяющих производить разные действия при создании объектов в зависимости от реальных потребностей в каждом конкретном случае.
Различают конструкторы следующих видов:
Конструктор по умолчанию.
Конструктор-инициализатор.
Конструктор копирования.
Конструктор преобразования типа.
Конструктор по умолчанию
Конструктор по умолчанию – специальный конструктор, который не имеет параметров.
Если Вы не написали в классе ни одного конструктора, компилятор автоматически создает пустой конструктор без параметров, т.н. конструктор по умолчанию.
TComplex::TComplex() {}
Впрочем, если вы хотите выполнить в конструкторе без параметров какие-то действия, вы можете создать такой конструктор самостоятельно.
TComplex::TComplex() { re = 0; im = 0 }
Конструктор по умолчанию – примеры использования
TComplex A();
TComplex *B = new TComplex();
В обоих случаях для создания объекта вызывается конструктор по умолчанию.
Наличие “()” в первом случае приводит к ошибке, когда компилятор не в состоянии различить прототип функции и объявление переменной объектного типа.
Наличие “()” во втором случае необязательно, оно лишь подчеркивает факт вызова метода (здесь ошибки нет, скобки можно использовать)!
Конструктор-инициализатор
Конструктор-инициализатор – специальный вид конструктора, который наряду с созданием объекта присваивает его полям начальные значения, получая их в качестве параметров.
TComplex::TComplex(int _re, int _im) {
re = _re;
im = _im;
}
Класс может иметь несколько конструкторов
с разным списком параметров! При этом
используется механизм перегрузки функций.
В каждом случае создания объекта компилятор разбирается,
какой из конструкторов необходимо вызвать.
Конструктор-инициализатор – примеры использования
TComplex A(1, 2), C(2, 3);
TComplex *B = new TComplex(3, 4);
В обоих случаях для создания объекта вызывается конструктор-инициализатор. В “()” перечисляются параметры.
Еще раз заметим: создание объекта – вызов метода.
Конструктор-инициализатор – еще один вариант синтаксиса
Существует еще один способ инициализации полей в конструкторе (кроме использованного в приведенной выше программе присваивания полям значений формальных параметров) – с помощью списка инициализаторов, расположенных после двоеточия между заголовком и телом конструктора.
Поля перечисляются через запятую. Для каждого поля в скобках указывается инициализирующее значение, которое может быть выражением.
Конструктор-инициализатор – еще один вариант синтаксиса
Вариант 1:
TComplex::TComplex(int _re, int _im) {
re = _re;
im = _im;
}
Вариант 2:
TComplex::TComplex(int _re, int _im):
re(_re), im(_im)
{
}
Конструктор-инициализатор – еще один вариант синтаксиса. Экзотика или необходимость?
Без этого способа не обойтись при инициализации полей-констант, полей-ссылок и полей-обьектов. В последнем случае будет вызван конструктор, соответствующий указанным в скобках параметрам.
Заметим, что, если ваш класс содержит поля-константы или поля-ссылки, то их обязательно необходимо инициализировать именно так, в противном случае вы получите сообщение об ошибке!
Конструктор преобразования типа
Допустим, у вас существует необходимость организовывать приведение типа (от объектного типа к некоторому другому).
Конструктор, принимающий ровно 1 параметр некоторого типа, называется конструктором преобразования типа, т.к. он осуществляет преобразование из этого типа в тип класса.
class TExample {
public:
int a;
TExample(int _a) {
a = _a;
}};
Конструктор копирования
Конструктор копирования – важный вид конструктора, который предназначен для создания объекта как копии уже существующего объекта.
Синтаксис объявления конструктора копирования:
<Имя класса> (const <Имя класса>&);
Пример:
TComplex::TComplex(const TComplex &C) {
re = C.GetRe();
im = C.GetIm();
}
Конструктор копирования. Случаи вызова
Как разобраться, в каких случаях компилятор из всех конструкторов выбирает для создания объекта именно конструктор копирования? Таких случаев 3:
При написании следующего объявления:
TComplex B(1, 2);
TComplex A = B;
При обмене данными с функцией, содержащей в качестве параметра или возвращаемого значения объект.
При работе механизма исключений (этот момент остается за рамками курса).
Конструктор копирования. Когда его нужно писать самому?
Если вы не указали явно для своего класса конструктор копирования, компилятор создаст его автоматически. При этом в конструктор будут включены инструкции копирования всех полей класса.
Так может быть достаточно во всем положиться на интеллектуальный компилятор и не писать самому конструктор копирования?
Да поможет нам «F1», и да сохранит нас «F2»
Конструктор копирования. Когда его нужно писать самому?
Ответ содержится в определении конструктора копирования. Конструктор копирования выполняет поэлементное копирование полей.
class TNamedComplex {
public:
int re; int im;
char *name;
…
};
…
TComplex B(1, 2, “b”);
TComplex A = B;
1
2
name
b
1
2
name
A
B
Конструктор копирования. Когда его нужно писать самому?
1
2
name
b
1
2
name
A
B
1
2
name
b
1
2
name
A
B
b
ОШИБКА!!!
ВЕРНО!!!
Конструктор копирования. Когда его нужно писать самому? Вывод
В том случае, если класс содержит поля-указатели, поэлементного копирования недостаточно.
Необходимо явно прописывать конструктор копирования, который выделит необходимую память и скопирует данные.
Пример создания конструктора копирования для класса TNamedComplex
TNamedComplex::TNamedComplex(TNamedComplex& C){
re = C.GetRe();
im = C.GetIm();
int len = strlen(C.GetName()) + 1;
name = new char[len];
strcpy(name, C.GetName());
}
Обязательная функция любого конструктора
Любой конструктор в первую очередь занимается тем, что выделяет память для полей класса и устанавливает связи между объектом и методами.
Важный момент: поля, не являющиеся указателями, создаются автоматически. Память под поля указатели необходимо выделять самостоятельно, явно прописав соответствующие инструкции в конструкторе!
class TNamedComplex {
public:
int re;
int im;
char *name;
};
re
im
name
?
методы
Конструкторы. Некоторые итоги
Конструктор – специальный метод, предназначенный для создания объекта.
Правило хорошего тона – реализовывать конструкторы в классе самостоятельно, не надеясь на компилятор.
Конструкторов обычно бывает несколько.
Выделяются конструктор по умолчанию, конструктор-инициализатор, конструктор приведения типа и конструктор копирования.
В случае, если класс содержит поля-указатели, поля ссылки или поля объекты, написание конструкторов является абсолютно необходимым.
Следующая тема
Далее мы рассмотрим, как происходит удаление объектов.
Павловская Т.А. C/C++ Программирование на языке высокого уровня.
Ален И. Голуб. Правила программирования на C/C++.
Из книг заимствованы различные идеи, элементы текста.
http://lye.upnet.ru
http://xaxa.h1.ru/jokes.html
Если не удалось найти и скачать доклад-презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:
Email: Нажмите что бы посмотреть