Слайд 2
Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
class Date
{
int day, month, year;
static
int default_day, default_month, default_year; public:
int *day_in_month;
Date(int d = 0, int m = 0, int y = 0);
void add_year(int n);
void add_month(int n);
void add_day(int n);
static void set_default(int d, int m, int y);
}
Слайд 3
Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
int main()
{
Date::set_default(4, 5, 1945);
Date today = Date(23,
6, 1983);
today.day_in_month = new int[12];
today.day_in_month[0] = 31;
today.day_in_month[1] = 30;
Date start_date = Date(21, 1, 1993);
today.day_in_month = new int[12];
today.day_in_month[0] = 31;
today.day_in_month[1] = 30;
return 0;
}
Слайд 4
Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
class Date
{
int day, month, year;
static
Date default_date;
public:
int *day_in_month;
Date(int d = 0, int m = 0, int y = 0);
void add_year(int n);
void add_month(int n);
void add_day(int n);
static void set_default(int d, int m, int y);
}
Слайд 5
Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
Date::Date(int dd, int mm, int yy)
{
day =
dd ? dd : default_date.day;
month = mm ? mm : default_date.month;
year = yy ? yy : default_date.year;
day_in_month = new int[12];
day_in_month[0] = 31;
day_in_month[1] = 30;
//..//
}
Слайд 6
Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
int main()
{
Date::set_default(4, 5, 1945);
for (int
i = 1; i < 1000; i++)
{
Sleep(10);
Date today;
}
return 0;
}
Скомпилируется программа?
Все ли хорошо работает?
Слайд 7
Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
class Date
{
int day, month, year;
static
int default_day, default_month, default_year;
public:
int *day_in_month;
Date(int d = 0, int m = 0, int y = 0); // день, месяц, год
~Date();
void add_year(int n); // прибавить n лет к d
void add_month(int n); // прибавить n месяцев к d
void add_day(int n); // прибавить n дней к d
static void set_default(int d, int m, int y);
};
Слайд 8
Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
Date::~Date()
{
delete[] day_in_month;
}
int main()
{
Date::set_default(4, 5, 1945);
for (int i = 1; i < 1000; i++);
{
Sleep(10);
Date today;
}
return 0;
}
Слайд 9
Копирование объектов класса
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
По умолчанию, объекты класса можно копировать.
int main()
{
Date::set_default(4,
5, 1945);
Date today = Date(23, 6, 1983);
Date xmas(25, 12, 1990); // сокращенная форма
Date birthday = today; // копирующая инициализация
return 0;
}
Копия объекта класса содержит копию каждого члена класса.
Слайд 10
Копирование объектов класса
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
class Date
{
int day, month, year;
static
int default_day, default_month, default_year;
public:
int *av_day;
Date(int d=0, int m=0, int y=0); // день, месяц, год
void add_year(int n); // прибавить n лет
void add_month(int n); // прибавить n месяцев
void add_day(int n); // прибавить n дней
static void set_default (int d, int m, int y);
};
Слайд 11
Копирование объектов класса
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
int main()
{
Date::set_default(4, 5, 1945);
Date today
= Date(23, 6, 1983);
*(today.av_day) = 10;
Date birthday=today;
*(birthday.av_day) = 15;
cout << *(today.av_day) << " " << *(birthday.av_day) << endl;
return 0;
}
Скомпилируется программа?
Что мы увидим на экране
после выполнения программы?
Слайд 12
Копирование объектов класса
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
Будьте внимательны, необдуманное прямое копирование приводит к ошибкам!!!
int main()
{
Date::set_default(4, 5, 1945);
Date today = Date(23, 6, 1983);
today.av_day = new int;
*(today.av_day) = 10;
Date birthday=today;
*(birthday.av_day) = 15;
cout << *(today.av_day) << " " << *(birthday.av_day) << endl;
return 0;
}
Слайд 13
Копирование объектов класса
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
int main()
{
Date::set_default(4, 5, 1945);
Date today
= Date(23, 6, 1983);
today.av_day = new int;
*(today.av_day) = 10;
Date birthday=today; // копирующая инициализация
*(birthday.av_day) = 15;
Date day_start;
day_start = today;
*(day_start.av_day) = 20;
cout << *(today.av_day) << " " << *(birthday.av_day) << " " <<
*(day_start.av_day) << endl;
return 0;
}
// копирующее присваивание
Скомпилируется программа?
Что мы увидим на экране
после выполнения программы?
Слайд 14
Копирование объектов класса
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
Можно избежать подобных аномалий, определив, что понимать под копированием
Date:
class Date
{
int day, month, year;
static Date default_date;
public:
/……/
Date(const Date&);
Date& operator=(const Date&);
};
Слайд 15
Копирование объектов класса
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
Date::Date(const Date& D) // копирующий конструктор
{
av_day =
new int;
*av_day = *(D.av_day);
day = D.day;
month = D.month;
year = D.year;
}
Date& Date::operator=(const Date& D) // присваивание
{
if (this != &D) // чтобы уберечься от присваивания самому себе: t=t
*av_day = *(D.av_day);
day = D.day;
month = D.month;
year = D.year;
return *this;
};
Слайд 16
Копирование объектов класса
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
int main()
{
Date::set_default(4, 5, 1945);
Date today
= Date(23, 6, 1983);
today.av_day = new int;
*(today.av_day) = 10;
Date birthday=today; // копирующая инициализация
*(birthday.av_day) = 15;
Date day_start;
day_start = today;
*(day_start.av_day) = 20;
cout << *(today.av_day) << " " << *(birthday.av_day) << " " <<
*(day_start.av_day) << endl;
return 0;
}
Слайд 17
Перегрузка операторов
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Как
и большинство других языков С++ поддерживает набор операторов для
встроенных типов.
Например:
постфиксный инкремент lvalue ++
постфиксный декремент lvalue - -
умножение expr * expr
сложение (плюс) expr + expr
И т.д
С++ позволяет объявить функции, определяющие смысл некоторых операторов.
Слайд 18
Перегрузка операторов
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Можно
объявить функции, определяющие смысл следующих операторов
Следующие операторы не могут
быть определены пользователем:
:: (разрешение области видимости);
. (выбор члена);
.* (выбор члена через указатель на член).
Слайд 19
Перегрузка операторов
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Имя
операторной функции начинается с ключевого слова operator, за которым
следует сам оператор; например operator<<.
Операторная функция объявляется и может быть вызвана, как любая другая функция.
Использование операторной функции как оператора является просто сокращенной формой ее явного вызова.
Слайд 20
Перегрузка операторов
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Имя
операторной функции начинается с ключевого слова operator, за которым
следует сам оператор; например operator<<.
Операторная функция объявляется и может быть вызвана, как любая другая функция.
Использование операторной функции как оператора является просто сокращенной формой ее явного вызова.
Слайд 21
Перегрузка операторов
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
class
complex {
double re, im;
public:
complex();
complex(double r, double i);
complex operator+
(complex);
complex operator* (complex);
};
Слайд 22
Перегрузка операторов
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
int
main()
{
complex a = complex(1, 3.1);
complex
b = complex(1.2, 2);
complex c = b;
a = b + c;
a = b.operator+(c);
b = b + c* a;
c = a*b + complex(1, 2);
return 0;
}
Слайд 23
Бинарные и унарные операторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК
имени П.А.Овчинникова
Бинарный оператор можно определить
либо в виде нестатической
функции-члена с од-ним аргументов
либо в виде функции-не-члена с двумя аргументами.
Для любого бинарного оператора @ выражение аа@ЬЬ интерпретируется либо как aa.operator@(bb) либо operator@(aa, bb)
Слайд 24
Бинарные и унарные операторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК
имени П.А.Овчинникова
class X {
public:
void operator+(int);
X(int);
};
void operator+ (X, X),
void operator+
(X, double);
void f(X a)
{
a + 1; // a.operator+(i)
1 + a; // operator+(X(l), a)
a + 1; // operator+(a, 1.0)
}
Слайд 25
Бинарные и унарные операторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК
имени П.А.Овчинникова
Унарный оператор, префиксный или постфиксный, можно определить либо
в виде нестатической функции-члена без аргументов, либо в виде функции-не-члена, с одним аргументом.
Для любого унарного оператора @ выражение @аа интерпретируется либо как aa.operator@ (), либо как operator@ (аа).
Слайд 26
Бинарные и унарные операторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК
имени П.А.Овчинникова
Для любого постфиксногооператора @ выражение аа@ интерпретируется либо
как aa.operator@ (nt) либо как operator@ (аа, int).
Если определены обе функции, для определения того, какую (возможно, никакую) из них использовать, применяется механизм разрешения перегрузки
Слайд 27
Бинарные и унарные операторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК
имени П.А.Овчинникова
class complex{
// члены (с неявным указателем this)
complex* operator&();
complex operator&(complex);
complex operator++(int);
complex operator& (X,X);
complex operator/();
};
//функции-не-члены
complex operator-(complex);
complex operator-(complex, complex);
complex operator--(complex&, int);
complex operator-();
complex operator- (complex, complex, complex);
complex operator%(complex);
// префиксный унарный оператор &
// бинарный оператор & (и)
// постфиксный инкремент
// ошибка: три операнда
// ошибка: унарный оператор
// префиксный унарный минус
// бинарный минус
// постфиксный декремент
// ошибка : отсутствует операнд
// ошибка : три операнда
// ошибка: унарный оператор %
Какие из определений функций верны?
Какие из прототипов функций верны?
Слайд 28
Перегрузка операторов
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Рассмотрим
бинарный оператор @, если х имеет тип X, а
у имеет тип Y, правила разрешения выражения х@у применяются следующим образом:
если X является классом, выяснить, определяется ли operator@ в качестве члена класса Х, либо базового класса Х;
если X определен в пространстве имен N, поискать объявления operator@ в N;
если У определен в пространстве имен М, поискать объявления operator@ в М.
Слайд 29
Операторы-члены и не-члены
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
Рекомендуется сводить к минимуму количество функций, непосредственно манипулирующих представлением
объекта.
Старайтесь определять в теле самого класса только те операторы, которые должны модифицировать значение первого аргумента, например оператор +=.
Операторы, которые просто выдают новое значение на основе своих аргументов, такие как +, рекомендуется определяють вне класса
Слайд 30
Операторы-члены и не-члены
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
class complex {
double re, im;
public:
complex&
operator+=(complex a); // требует доступа к представлению
// . . .
};
complex operator+(complex a, complex b)
{
complex r = a;
return r += b; // доступ к представлению при помощи +=
}
inline complex& complex::operator+=(complex a)
{
re += a.re;
im += a.im;
return *this;
}
Слайд 31
Операторы-члены и не-члены
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени
П.А.Овчинникова
void f(complex x, complex y, complex z)
{
complex rl =
x + y + z;
complex r2 = x;
r2 += y,
r2 += z;
complex d = 2 + b;
}
// rl = operator+(operator+(x,y), z)
// r2 = x
// r2.operator+= (y)
// r2.operator+=(z)
// operator+(2,b)
// Ошибка!!!