Вы находитесь на странице: 1из 52

Лекция №1. Основы объектно-ориентиро- ванного программирования с точки зрения пользователей классов

Понятие класса и объекта Порождение объектов, конструкторы Динамические и статические методы класса Перегрузка функций и операций Аргументы, задаваемые по умолчанию Тип данных «ссылка» Работа с динамическими объектами

Понятие класса и объекта

В языке Си++ появился новый тип данных - класс

Класс - это тип данных, который содержит данные и функции для их обработки

Класс = тип данных "структура" + функции

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

Объект обладает состоянием и поведением

2 Объект = состояние + поведение

Понятие класса и объекта

Класс

тип данных

описание свойств и методов, т.е. возможностей

QDate

Объект

переменная

Конкретное состояние + изменение состояния посредством методов

QDate birthday(1990, 3, 23)

3

год, месяц, день

год=1990,месяц=3,день=23

--------------------

 

--------------------

задать день, месяц, год

задать день, месяц, год

считать день, месяц, год

считать день, месяц, год

получить день недели

получить день недели

сравнить с другой

сравнить с другой датой

датой

Состояние объекта

Состояние — это то, что хранится в объекте

Состояние объекта характеризуется перечнем всех полей (свойств) данного объекта и текущими значе- ниями каждого из этих полей

Пример состояния объекта birthday:

Свойство

год

месяц

день

Значение

1990

3

23

Состояние объекта может измениться только в ре- 4 зультате вызова методов

Поведение объекта

Поведение – это набор функций, которые могут быть вызваны применительно к объекту

Функции, связанные с объектом, будем называть ме- тодами

Пример поведения объекта birthday:

задать год, месяц, день считать год, месяц, день получить день недели сравнить с другой датой (больше, меньше или равна)

Порождение объекта

Так как объект является переменной типа «класс», то в простейшем случае объект создается так же как и любая другая переменная:

<имя<имя класса>класса> <имя<имя объекта>;объекта>;

Пример:

QDate date; // создаем «неопределенную» дату - // дата, месяц и год не определены

Порождение объекта

Можно создать объект с заранее заданным значени- ем свойств, выполнив его инициализацию, напри- мер, задав дату 23.03.1990

Пример:

QDate birthday(1990, 3, 23); // конкретная // дата рождения

Для этого класс должен содержать специальный метод - конструктор
7

Конструкторы

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

Конструктором в языке Си++ считается метод, имя которого совпадает с именем класса

Конструктор не имеет возвращаемого значения

Класс может иметь несколько конструкторов (они должны различаться аргументами)

Конструкторы класса QDate

QDate () /*используется для создания «неопре- деленной» даты*/

QDate ( int y, int m, int d ) /*используется для создания даты с заданными годом y, месяцем m и днем d*/

Использование конструкторов

Конструктор вызывается при объявлении перемен- ной-объекта

Если конструктор имеет параметры, то они указы- ваются как аргументы создаваемой переменной:

<имя<имя класса>класса> <имя<имя объекта>объекта> (<аргументы(<аргументы конструктора>);конструктора>);

Пример использования конструкторов

У класса QDate имеются следующие конструкторы:

QDate ()

QDate ( int y, int m, int d )

Следовательно, возможны следующие варианты со- здания переменных типа QDate:

QDate nullDate; // «неопределенная» дата

QDate birthday(1990, 3, 23); // конкретная дата 11 // рождения

Задание

У класса QString («строка») имеются следующие конструкторы:

QString () /* используется для создания «пустой» строки*/

QString ( const char * str ) /*используется для создания строки, инициализируемой ASCII строкой str*/

QString ( int size, char ch ) /*используется для создания строки длиной size, состоящей из одинаковых символов ch*/

Создайте строку str, содержащую последователь-

12 ность символов "AAAAAAAAAAAAAAA" (15 символов)

Порождение объектов-переменных

// Вариант 1 - предпочтительный QString str(15, 'A');

// Вариант 2 QString str("AAAAAAAAAAAAAAA");

Динамические и статические методы класса

Методы, которые применяются к отдельным объектам, называются динамическими

Методы, которые относятся к классу в целом, на- зываются статическими

Динамические методы выполняются над конкретным объектом, а статические методы выполняются безотносительно какого-либо объекта

Пример динамических и статических методов класса

Класс

QDate имеет

методы:

следующие

динамические

bool setDate ( int year, int month, int day ) //задает объекту некоторую дату

int weekNumber ( ) const //возвращает номер недели

Класс QDate имеет следующий статический метод:

bool isValid ( int year, int month, int day ) //проверяет корректность даты

Пример использования динамических и статических методов класса

// Создаем объекты QDate date1(1991, 11, 15); QDate date2(1991, 11, 15);

// Вызов динамического метода – изменяем // состояние объекта date1 date1.setDate(2000, 12, 31);

объекта date1 date1.setDate(2000, 12, 31); обращение к объекту // Вызов

обращение к объекту

// Вызов динамического метода – считываем // состояние объекта date2 int week = date2.weekNumber();

объекта date2 int week = date2.weekNumber(); обращение к объекту // Вызов

обращение к объекту

// Вызов статического метода – обращения к // объектам не происходит

Обращение к динамическим методам класса

<объект>.<имя<объект>.<имя метода>(<аргументы>)метода>(<аргументы>)

При обращении к динамическим методам класса необходимо указывать объект (значение или указатель), к которому осуществляется обращение

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

При обращении к динамическим методам класса используется оператор доступа «точка» (или

Пример использования динамических методов

Метод класса QString int length () const

Свободная функция int strlen (const char *str)

QString str("Example"); char str[] = "Example";

int len = str.length(); int len = strlen(str);

Задание

У класса QString имеется динамический метод:

QString & append ( const QString & str )

//добавляет строку str в конец строки

Имеются четыре строки:

QString FIO(""); QString fisrtName("Козлов"); QString name("Андрей"); QString patronymic("Петрович");

// ФИО // фамилия // имя // отчество

Записать в строку FIO фамилию, имя и отчество

19 человека, разделив их пробелами

Пример использования динамических методов

QString space(" ");

// разделитель

// Формируем ФИО человека FIO.append(fisrtName); FIO.append(space); FIO.append(name); FIO.append(space); FIO.append(patronymic);

//"Козлов" //"Козлов " //"Козлов Андрей" //"Козлов Андрей " //"Козлов Андрей Петрович"

Использование «цепочки» динамических методов

21

В

качестве

выражения,

стоящего

слева

от

вызов

операции «точка»,

метода, возвращающего объект

может

выступать

<объект>.<метод<объект>.<метод 1_1>.<метод1_1>.<метод 2_1>2_1>

класс 1  метод 1_1  метод 1_2
класс 1
 метод 1_1
 метод 1_2

метод 1_1 возвращает экземпляр класса 2

класс 2

метод 2_1

метод 2_2

метод 2_3

Пример использования «цепочки» динамических методов

Метод класса QDate

QString toString ( Qt::DateFormat format) const

//возвращает строку, содержащую дату

Метод класса QString

QString & prepend ( const QString & str )

//предваряет строку заданной подстрокой

22

Пример:

QDate date(2009, 3, 23); date.toString("dd.MM.yyyy").prepend("My birtday is ");

3, 23); date.toString( "dd.MM.yyyy" ).prepend( "My birtday is " ); QString ("23.03.2009")
3, 23); date.toString( "dd.MM.yyyy" ).prepend( "My birtday is " ); QString ("23.03.2009")

QString ("23.03.2009")

Обращение к статическим методам класса

<имя<имя класса>::<имякласса>::<имя метода>(<аргументы>)метода>(<аргументы>)

При обращении к статическим методам класса используется оператор области видимости ::::

При обращении к статическим методам класса необходимо указывать имя класса

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

Пример использования статических методов

Метод класса QString

int

compare (

const QString & s1, const QString & s2 )

QString str1("one"); QString str2("two");

int result =

QString::compare(str1,

str2);

Свободная функция int strcmp( const char *s1, const char *s2 )

char str1[] = "one"; char str2[] = "two";

int result = strcmp(str1, str2);

Задание

У класса QDate имеется статический метод, кото- рый возвращает текущую дату:

QDate currentDate ()

Создайте дату, соответствующую текущему дню и запомните ее в объекте QDate cDate;

Пример использования статического метода

QDate cDate;

// Создаем и запоминаем сегодняшнюю дату cDate = QDate::currentDate();

дату cDate = QDate:: currentDate(); объект, содержащий текущую дату 26
дату cDate = QDate:: currentDate(); объект, содержащий текущую дату 26

объект, содержащий текущую дату

Задание

У класса QDate имеется статический метод, кото- рый возвращает текущую дату:

QDate currentDate ()

И ряд динамических методов:

int day () const int dayOfWeek () const int dayOfYear () const int daysInMonth () const int daysInYear () const int daysTo ( const QDate & d ) const

Определите кол-во дней в текущем году и запи-

27 шите в переменную cyDays

Пример использования статических методов

int cyDays; // Определяем кол-во дней в текущем году cyDays = QDate::currentDate().daysInYear();

году cyDays = QDate:: currentDate().daysInYear(); объект, содержащий текущую дату
году cyDays = QDate:: currentDate().daysInYear(); объект, содержащий текущую дату

объект, содержащий текущую дату

// или

QDate cDate = QDate::currentDate(); cyDays = cDate.daysInYear();

Перегрузка функций в языке Си++

29

В языке Си++ допускается наличие нескольких функций с одинаковым именем, если они разли- чаются количеством и/или типами аргументов

Различие в типе возвращаемого значения не учи- тывается

Какую из перегруженных функций вызывать, язык программирования определяет по типам фактиче- ских аргументов

Перегрузка методов

Класс может содержать несколько методов с одина- ковым именем

Правила идентичны функциями

работы

с

правилам

перегруженными

работы

с

методами

перегруженными

Задание

У класса QString имеется несколько методов для удаления подстроки:

QString & remove ( int position, int n ) //удаляет n символов, начиная с позиции position QString & remove ( const QString & str) //удаляет все вхождения подстроки str

QString & remove ( QChar ch) //удаляет все вхождения символа ch

Определите результат следующей программы:

QString str("кот, который живет на крыше"); QString cat("кот");

31 str.remove(1,1).remove(cat);

Вызов перегруженных методов

str.remove(1,1).remove(cat);

методов str.remove(1,1).remove(cat); вызов метода QString & remove ( int
методов str.remove(1,1).remove(cat); вызов метода QString & remove ( int

вызов метода QString & remove ( int position, int n ) результат "кт, который живет на крыше"

вызов метода QString & remove ( const QString & str ) результат "кт, орый живет на крыше"

Перегрузка операций

Язык Си++ позволяет переопределить (перегру- зить) поведение стандартных операций (например +, =, [] и т.д.) применительно к классу

Пример. В классе QDate определены следующие операции сравнения:

bool operator!= ( const QDate & d ) const

( const QDate & d ) const

bool operator<= ( const QDate & d ) const bool operator== ( const QDate & d ) const

( const QDate & d ) const

33 bool operator>= ( const QDate & d ) const

bool operator<

bool operator>

Перегрузка операций

Следовательно допустимы следующие выражения:

QDate date1(2009, 3, 4); QDate date2(2009, 4, 3);

date1 < date2;

date1.operator<(date2); // идентичная запись

// истина

date1 == QDate::currentDate(); // ложь
34

Перегрузка операций

Операция может быть задана как метод класса или как свободная функция

Метод, определяющий операцию, имеет следую- щий вид:

<тип<тип операции>операции> operatoroperator <знак<знак операции>операции> (<правый(<правый операнд>)операнд>)

Пример:

bool operator!= ( const QDate & d ) const

Замечание.

Левый

операнд

не

указывается,

т.к.

35 предполагается, что это объект класса

Перегрузка операций

Свободная

функция,

определяющая

имеет следующий вид:

операцию,

<тип<тип операции>операции> operatoroperator <знак<знак операции>операции> (<левый(<левый операнд>,операнд>, <правый<правый операнд>)операнд>)

Пример:

const QString operator+ ( char ch, const QString & s )

QString str = 'A' + QString("BCD"); // str = "ABCD"

Задание

Для класса QString операция «меньше» перегру- жена следующим образом:

методы:

bool operator< (const QString & other) const bool operator< (const QLatin1String & other) const bool operator< (const QByteArray & other) const bool operator< (const char * other) const

свободная функция:

bool operator< (const char *s1, const QString &s2)

Определите, допустимо ли ее так использовать:

37

QString str1("рок"), str2("рык"); str1 < str2; //1 'р' < str1; //2

Перегрузка операций

Выражение str1 < str2 допустимо, т.к. сравнива- ются два объекта типа QString и имеется соответ- ствующий метод

bool operator< (const QString & other) const

Выражение 'р' < str1 недопустимо, т.к. левым операндом является символ, а свободная функция, определяющая операцию, требует массив симво- 38 лов

Аргументы, задаваемые по умолчанию

Язык Си++ предоставляет возможность устанавли- вать значения аргументов функции по умолчанию, если при вызове функции они не были указаны

Значение по умолчанию указывается в заголовке функции в виде инициализации соответствующих аргументов:

<тип> <имя функции> (<тип> <имя аргумента> = <значение по умолчанию>)

Аргументы со значением по умолчанию распола-

Пример использования аргументов, задаваемых по умолчанию

В классе QString определен метод, преобразующий целое число n в строку:

QString & setNum ( int n, int base = 10 )

Второй аргумент base

определяет основание си-

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

QString str; str.setNum(11, 2);

40 str.setNum(11);

// “1011” // “11”

Задание

Метод класса QString

int indexOf

(

const

QString

&

str,

int

from

=

0,

Qt::CaseSensitivity cs = Qt::CaseSensitive ) const

/* выполняет поиск первого вхождения заданной подстроки str */

Найдите в строке

QString str("кот, который живет на крыше");

подстроку "тор", если все аргументы, заданные по умолчанию, имеют приемлемые значения

Использование аргументов, задаваемых по умолчанию

// Передаем только один аргумент, остальные // аргументы принимают значение по умолчанию int index = str.indexOf( QString("тор") );

Тип данных «ссылка»

В языке Си++ введен новый тип данных — ссылка

Ссылка ведет себя как указатель, но не требует

применения операций **

->->

&&

Объявление переменной типа «ссылка»:

<тип<тип данных>данных> &&<имя<имя переменной>;переменной>;

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

Пример использования ссылочных аргументов

void swap(int *a, int *b)

void swap(int &a, int &b)

{

{

 

int tmp; tmp = *a;

int tmp; tmp = a;

*a = *b;

a = b;

*b = tmp;

b = tmp;

}

}

44

void main(void)

void main(void)

{

{

 

int k = 5, m = 2;

int k = 5, m = 2;

swap(&k, &m); // k = 2, // m = 5

swap(k, m);

// k = 2, // m = 5

}

}

Использование ссылок применительно к классам

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

Пример:

int compare

(

const

QString

&

other

)

const

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

QString str1("рок"), str2("рык");

str1.compare(str2);

45

"рок" ), str2( "рык" ); str1.compare(str2); 45 объект передается по ссылке

объект передается по ссылке

Использование ссылок применительно к классам

Метод может возвращать ссылку на объект, к кото- рому он был применен. Это позволяет строить «цепочки» обращений к одному и тому же объекту

Пример:

QString str("1234112"); str.remove("1").remove("2"); //str = "34"

"1" ).remove( "2" ); //str = "34" где результат выражения объект

где

результат выражения объект str = "2342"

QString

Qt::CaseSensitivity cs = Qt::CaseSensitive )

&

(

QString

remove

const

&

str,

// удаляет все вхождения заданной подстроки
46

Порождение временных объектов

Кроме объектов-переменных могут существовать временные объекты

Временный объект не имеет имени и существует пока вычисляется выражение, в котором он был создан

Явное создание временного объекта <имя<имя класса>(<аргументыкласса>(<аргументы конструктора>)конструктора>) Пример:

QString str = QString("Сегодня ") + QString("суббота");

47

"Сегодня " ) + QString( "суббота" ); 4 7 временные объекты типа QString
"Сегодня " ) + QString( "суббота" ); 4 7 временные объекты типа QString
"Сегодня " ) + QString( "суббота" ); 4 7 временные объекты типа QString

временные объекты типа QString

Порождение временных объектов

Создание временного объекта функциями и мето- дами, которые как результат возвращают объект

Пример:

Метод класса QDate

QString toString ( Qt::DateFormat format) const // возвращает строку, содержащую дату

48

QDate date(2007, 7, 7); // счастливая дата QString str = date.toString("dd.MM.yyyy");

дата QString str = date.toString( "dd.MM.yyyy" ); временный объект типа QString

временный объект типа QString

Динамическое создание объектов

В языке С++ для динамического создания объектов используется оператор newnew, возвращающий указа- тель на данный объект (преобразования типов не требуется):

newnew <тип<тип данных>данных>

При создании массива объектов их количество ука- зывается в квадратных скобках:

newnew <тип<тип данных>[<кол-воданных>[<кол-во элементов>]элементов>]

Оператор newnew отличается от функции mallocmalloc под- держкой дополнительных возможностей ООП

Динамическое уничтожение объектов

Для динамического уничтожения объектов (с осво- бождением выделенной памяти) используется оператор deletedelete:

deletedelete <указатель<указатель нана объект>объект>

При удалении динамически выделенного массива используется следующий синтаксис:

deletedelete [][] <указатель<указатель нана первыйпервый элемент>элемент>

Задание

Создайте динамический массив relations из N строк (типа QString), в каждой из которых хранит- ся ФИО родственника

Запишите в первую строку ФИО своего родствен- ника

Освободите память из-под выделенного массива

Динамическое создание и уничтожение объектов

int N = 5;

// кол-во родственников

// Создаем N родственников QString * relations = new QString[N];

// Записываем родственника relations[0] = QString("Иванов А.В.");

// Освобождаем память из под N родственников delete [] relations;