Слайд 1Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
ОСНОВЫ ПРОГРАММИРОВАНИЯ НА ЯЗЫКЕ С++
ООП
Слайд 2Спецификатор inline.
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Функцию можно определить со
спецификатором inline. Такие функции называются встроенными.
#include
using namespace std;
inline void hello()
{
cout << "hello";
}
int main()
{
hello(); //Call it like a normal function...
return 0;
}
Слайд 3Спецификатор inline.
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Как только программа пройдет
процесс препроцессинга, вызов hello(); будет заменен на код функции.
#include
using namespace std;
int main()
{
cout << "hello"; //Call it like a normal function...
return 0;
}
Слайд 4Статические переменные
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Локальная переменная создается в
момент выполнения строки, содержащей ее определение.
По умолчанию это происходит при каждом вызове функции и каждый раз создается новая переменная.
Если локальная переменная объявлена как static, при всех вызовах функции для хранения ее значения будет использоваться единственный, статически размещенный в памяти объект.
Она будет проинициализирована только при первом выполнении строки, содержащей ее определение.
Слайд 5Статические переменные
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
#include
using namespace std;
void
f(int а)
{
while (а--)
{
static int n = 0; // инициализируется один раз
int x = 0; //инициализируется 'а' раз при каждом вызове /()
cout << "n= " << n++ << ", х=" << x++ << endl;
}
}
int main()
{
f(3);
return 0;
}
Слайд 6Указатель на функцию
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
С функцией можно
проделать только две вещи: вызвать ее и получить ее адрес.
Указатель, полученный взятием адреса функции, можно затем использовать для вызова функции.
Слайд 7Указатель на функцию
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
#include
#include
using
namespace std;
void error(string s)
{
cout << s;
}
int main()
{
void(*efct) (string); // указатель на функцию
efct = &error; // efct указывает на функцию error
efct("ошибка"); // вызов error через efct
return 0;
}
Слайд 8Директива typedef
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Директива typedef позволяет задать
синоним для встроенного либо пользовательского типа данных
typedef double wages;
typedef int *Pint;
// double hourly, weekly;
wages hourly, weekly;
// int *table[ 10 ];
Pint table[10];
Слайд 9Классы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Класс — это определяемый пользователем
тип.
Целью введения концепции классов в С++ является предоставление программисту средств создания новых типов, которые настолько же удобны в использовании, как и встроенные.
Слайд 10Функции-члены
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Рассмотрим реализацию концепции даты с
использованием структуры Date.
struct Date
{ // представление
int day, month, year;
};
void init_date(Date& date, int d, int m, int y); // инициализация d
void add_year(Date& date, int n); // прибавить n лет к d
void add_month(Date& date, int n); // прибавить n месяцев к d
void add_day(Date& date, int n); // прибавить n дней к d
Здесь нет явной связи между типом данных и функциями.
Слайд 11Функции-члены
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
void init_date(Date& date, int d,
int m, int y)
{
date.day = d;
date.month = m;
date.year = y;
}
void add_year(Date& date, int n)
{ date.year += n; }
void add_month(Date& date, int n)
{ date.m += n; }
void add_day(Date& date, int n)
{ date.d += n; }
int main()
{
Date birthday;
init_date(birthday, 10, 8, 1990);
return 0;
}
Слайд 12Функции-члены
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Cвязь можно установить, объявив функции
в качестве членов структуры.
struct Date
{
int day, month, year;
void init_date(int d, int m, int y); // инициализация
void add_year(int n); // прибавить n лет
void add_month(int n); // прибавить n месяцев
void add_day(int n); // прибавить n дней
};
Слайд 13Функции-члены
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
void Date::init_date(int d, int m,
int y)
{
day = d; month = m; year = y;
}
void Date::add_year(int n)
{ year += n; }
void Date::add_month(int n)
{ month += n; }
void Date::add_day(int n)
{ day += n; }
int main()
{
Date birthday;
birthday.init_date(10, 8, 1990);
Date today;
today.day = 31;
today.month = 2;
today.year = 1990;
return 0;
}
Проблемы контроля доступа
к полям структуры
Слайд 14Управление доступом
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
class Date
{
int
day, month, year;
public:
void init_date(int d, int m, int y); // инициализация
void add_year(int n); // прибавить n лет
void add_month(int n); // прибавить n месяцев
void add_day(int n); // прибавить n дней
};
int main()
{
Date birthday;
birthday.init_date(10, 8, 1990);
Date today;
today.day = 31; ОШИБКА !!!
today.month = 2; ОШИБКА !!!
today.year = 1990; ОШИБКА !!!
return 0;
}
Слайд 15Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Конструктор распознается по
имени, которое совпадает с именем самого класса
class Date
{
int day, month, year;
public:
Date(int d, int m, int y); // конструктор класса
void add_year(int n); // прибавить n лет
void add_month(int n); // прибавить n месяцев
void add_day(int n); // прибавить n дней
};
Слайд 16Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Конструктор распознается по
имени, которое совпадает с именем самого класса
int main()
{
Date today = Date(23, 6, 1983);
Date xmas(25, 12, 1990);
Date birthday;
Date release(10, 12);
}
Скомпилируется программа?
Что мы увидим на экране
после выполнения программы?
Слайд 17Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Довольно часто удобно
иметь несколько способов инициализации объекта класса.
class Date
{
int day, month, year;
public:
Date(int d, int m, int y); // день, месяц, год
Date(int d, int m); // день, месяц, текущий год
Date(int d); // день, текущие месяц и год
Date(), // дата по умолчанию — сегодня
Date(const char*); // дата в строковом представлении
void add_year(int n); // прибавить n лет
void add_month(int n); // прибавить n месяцев
void add_day(int n); // прибавить n дней
};
Как оптимизировать данный класс?
Слайд 18Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Подходите разумно к
перегрузке функций
class Date
{
int day, month, year;
public:
Date(int d=0, int m=0, int y=0); // день, месяц, год
Date(const char*); // дата в строковом представлении
void add_year(int n); // прибавить n лет
void add_month(int n); // прибавить n месяцев
void add_day(int n); // прибавить n дней
};
Слайд 19Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Довольно часто удобно
иметь несколько способов инициализации объекта класса.
Date::Date(int dd, int mm, int yy)
{
day = dd ? dd : default_day;
month = mm ? mm : default_month;
year = yy ? yy : default_year;
}
Слайд 20Статические члены
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Переменная, которая является частью
класса, но не является частью объекта этого класса, называется статическим членом.
Существует ровно одна копия статического члена, в отличии от обычных членов, когда каждый объект класса имеет свои независимые члены.
Обращаться к статическим элементам класса можно не создавая объект.
Слайд 21Статические члены
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
class Date
{
int
day, month, year;
static Date default_date;
public:
Date(int d=0, int m=0, int y=0); // день, месяц, год
Date(const char*); // дата в строковом представлении
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);
};
void Date::set_default (int d, int m, int y)
{
default_day = d;
default_month = m;
default_year = y;
}
int Date::default_day = 1;
int Date::default_month = 1;
int Date::default_year=1970;
Слайд 22Статические члены
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
int main()
{
Date::set_default(4,
5, 1945);
Date::add_day(3);
Date today = Date(23, 6, 1983);
today.add_day(3);
return 0;
}
Скомпилируется программа?
Слайд 23Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 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);
}
Слайд 24Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 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;
}
Слайд 25Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 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);
}
Слайд 26Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 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;
//..//
}
Слайд 27Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
int main()
{
Date::set_default(4, 5, 1945);
for (int i = 1; i < 1000; i++)
{
Sleep(10);
Date today;
}
return 0;
}
Скомпилируется программа?
Все ли хорошо работает?
Слайд 28Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 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);
};
Слайд 29Конструкторы и деструкторы
Никитин Михаил Евгеньевич, 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;
}
Слайд 30Копирование объектов класса
Никитин Михаил Евгеньевич, 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;
}
Копия объекта класса содержит копию каждого члена класса.
Слайд 31Копирование объектов класса
Никитин Михаил Евгеньевич, 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);
};
Слайд 32Копирование объектов класса
Никитин Михаил Евгеньевич, 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;
}
Скомпилируется программа?
Что мы увидим на экране
после выполнения программы?
Слайд 33Копирование объектов класса
Никитин Михаил Евгеньевич, 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;
}
Слайд 34Копирование объектов класса
Никитин Михаил Евгеньевич, 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;
}
// копирующее присваивание
Скомпилируется программа?
Что мы увидим на экране
после выполнения программы?
Слайд 35Копирование объектов класса
Никитин Михаил Евгеньевич, 2015
ГБПОУ ПК имени П.А.Овчинникова
Можно избежать подобных
аномалий, определив, что понимать под копированием Date:
class Date
{
int day, month, year;
static Date default_date;
public:
/……/
Date(const Date&);
Date& operator=(const Date&);
};
Слайд 36Копирование объектов класса
Никитин Михаил Евгеньевич, 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;
};
Слайд 37Копирование объектов класса
Никитин Михаил Евгеньевич, 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;
}