Д.з. на 3 марта

32
Д.з. на 3 марта 10.03.2009 Язык С++ - занятие 4 1

Upload: charis

Post on 14-Jan-2016

31 views

Category:

Documents


0 download

DESCRIPTION

Д.з. на 3 марта. Задача 1: треугольный массив. int* a[10]; // Создаем.. for (int i = 0; i

TRANSCRIPT

Page 1: Д.з. на  3  марта

Д.з. на 3 марта

10.03.2009 Язык С++ - занятие 4 1

Page 2: Д.з. на  3  марта

Задача 1: треугольный массивint* a[10];

// Создаем..for (int i = 0; i<10; i++) {

a[i] = new int[i+1];}

// Заполняем for (int i = 0; i<10; i++) {

for (int j = 0; j<=i; j++) {a[i][j] = (i == j);

}}

// Печатаемfor (int i = 0; i<10; i++) {

for (int j = 0; j<=i; j++) {cout << a[i][j] << " ";

}cout << "\n";

}

4.03.2008 Язык С++ - занятие 4 2

Page 3: Д.з. на  3  марта

Задача 3: двоичный поиск• Делим массив пополам• Смотрим, в какой половине граница четных и

нечетных• Повторяем то же с этой половиной• И так в цикле, пока длина куска массива >1

10.03.2009 Язык С++ - занятие 4 3

Page 4: Д.з. на  3  марта

Задача 3: код// Предполагаем, что: длина массива > 1, сначала идут несколько// (>=1) четных чисел, потом несколько (>=1) нечетныхint numEven(int* a, int size){

int beg = 0, end = size - 1;

while (end - beg > 1) {int mid = (beg + end) / 2;if (a[mid]%2 == 0)

beg = mid;else

end = mid;}return end; // Тут всегда будет end - beg == 1

}// Пример вызоваint a[10];…cout << numEven(a, 10);

10.03.2009 Язык С++ - занятие 4 4

Page 5: Д.з. на  3  марта

Д.з. на 10 марта

10.03.2009 Язык С++ - занятие 4 5

Page 6: Д.з. на  3  марта

Задача 1: order// Вспомогательная функция:// Упорядочиваем два числаvoid order(int& x, int& y){

if (x > y) {int tmp = x;x = y;y = tmp;

}}

void order(int& x, int& y, int& z){

order(x, y);order(x, z);order(y, z);

}

// Пример вызова:int a = 3, b = 1, c = 2;order(a, b, c);cout << a << b << c;

10.03.2009 Язык С++ - занятие 5 6

Page 7: Д.з. на  3  марта

Задача 2: Стек фиксированного размера

class stack {int stk[100];int size;

public:stack() : size(0){}

void push(int i){ stk[size++] = i;}

int pop(){ return stk[--size];}

};

stack s; // Примерs.push(5);s.push(10);s.push(2);cout << s.pop(); // Печатает 2int i = s.pop() – s .pop();

// В последней строчке // результат не определен!

10.03.2009 Язык С++ - занятие 5 7

Page 8: Д.з. на  3  марта

Задача 3: динамический стекclass dynstack {

int size; // Количество элементовint maxsize; // Макс. количествоint* p; // Отведенная память

public:dynstack() : size(0), maxsize(10){

p = new int[maxsize];}

~dynstack(){

delete [] p; // Многие забыли..}

void push(int val){

if (size == maxsize) { // Нет места?int* newp = new

int[maxsize*2];

// Копируемfor (int i=0; i<size; i++) {

newp[i] = p[i];}

maxsize *= 2;

delete [] p;p = newp; // Переставляем

} // указатель

p[size++] = val;}

int pop(){

return p[--size];}

};10.03.2009 Язык С++ - занятие 4 88

Page 9: Д.з. на  3  марта

Классы (продолжение)

10.03.2009 Язык С++ - занятие 4 9

Page 10: Д.з. на  3  марта

Объявление классаclass abc;

class klm {abc* p;…

};

class abc {klm* q;…

};

10.03.2009 10Язык С++ - занятие 4

Page 11: Д.з. на  3  марта

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

вообще нет конструкторов.

class abc {… нет ни одного

конструктора …};

Хотелось бы писать:abc x;abc a[10];

Автоматически добавляется:

abc (){}

И из-за этого бывают проблемы..

class abc { … нет конструкторов …};

abc x; // Все в порядке

Перестанет работать, когда мы добавим любой конструктор

10.03.2009 Язык С++ - занятие 4 11

Page 12: Д.з. на  3  марта

Наследование

10.03.2009 Язык С++ - занятие 4 12

Page 13: Д.з. на  3  марта

Пример – время с секундамиclass time_with_sec : public time { int sec;public: time_with_sec(int h, int m, int s); void inc_sec(); void print();};

time_with_sec::time_with_sec(int h, int m, int s):

time(h, m), sec(s){}

void time_with_sec::inc_sec(){ sec++; if ( sec == 60 ) {

sec = 0; inc(); }}

void time_with_sec::print(){ time::print(); cout << "." << sec;}

// использование time_with_sectime_with_sec ts(12, 30, 45);ts.inc();ts.inc_sec();ts.print();

10.03.2009 Язык С++ - занятие 4 13

Page 14: Д.з. на  3  марта

Замечания1. public наследование (другие почти не встречаются)2. Слова: базовый класс / производный класс3. Можем использовать поля и методы базового класса, как

будто они наши собственные 4. Можем доопределять поля и методы (sec, inc_sec)5. конструктор базового класса вызывается в списке

инициализации6. time::print() – указываем, что нас интересует именно метод

базового класса7. Самое главное – можно переопределять методы8. Переопределяемые методы надо определять, как виртуальные

(практически всегда)

10.03.2009 Язык С++ - занятие 4 14

Page 15: Д.з. на  3  марта

protected поля и методыТакие методы доступны из производных классов. Например, м.б. лучше в time :

class time {protected: int hour, min; // Можно использовать в time

// и в производных классах …

10.03.2009 Язык С++ - занятие 4 15

Page 16: Д.з. на  3  марта

Виртуальные функции (!!!) Правило:

Если вы собираетесь переопределить функцию в производном классе, то в базовом классе вы должны описать ее, как виртуальную.

class time {virtual void print();…

10.03.2009 Язык С++ - занятие 4 16

Page 17: Д.з. на  3  марта

Разница между виртуальными и не виртуальными функциями. Динамическое связывание.

time* p;

if ( …какое-то условие… ) { p = new time(8, 50);} else { p = new time_with_sec (11, 30, 15);}

// на что указывает p ??// - неизвестно..

p->print(); // Какой print // будет

вызван?

Если функция виртуальная, то будет вызываться «правильный» print: time::print() или time_with_sect::print()в зависимости от типа p

Называется: динамическое связывание (dynamic binding) или позднее связывание (late binding)

10.03.2009 Язык С++ - занятие 4 17

Page 18: Д.з. на  3  марта

Почему это важно. void my_print(time& p){ cout << "Московское время:"; p.print();}

time t1(8, 50);time_with_sec t2(11, 30, 15);

my_print(t1);my_print(t2);

Будут вызваны разные print ! Виртуальные функции позволяют писать код, который умеет

работать с разными типами!Называется: полиморфизм

10.03.2009 Язык С++ - занятие 4 18

Page 19: Д.з. на  3  марта

Еще другими словами: как понимать слово virtual... Если нам дали класс, в котором есть

виртуальная функция:

class abc { virtual void f();

Это надо читать так:«… Функцию f вы можете переопределить и задать свой вариант…»

10.03.2009 Язык С++ - занятие 4 19

Page 20: Д.з. на  3  марта

Как это все реализовано?Тут объяснялось, как обычно реализуются

виртуальные функции (таблица виртуальных методов, vtable).

Все рисовалось на доске, в слайдах этого нет…

10.03.2009 Язык С++ - занятие 4 20

Page 21: Д.з. на  3  марта

Чисто виртуальные функции, абстрактные

базовые классы

10.03.2009 Язык С++ - занятие 4 21

Page 22: Д.з. на  3  марта

Пример: фигурыРассмотрим набор классов для геометрических фигур: квадраты, ромбы, круги, треугольники и т.д.

class shape {

protected:int x, y;

public:virtual void draw()

= 0;shape(int x_, y_) :

x(x_), y(y_){}

… еще методы (площадь, периметр и т.д.) …};

10.03.2009 Язык С++ - занятие 4 22

Page 23: Д.з. на  3  марта

Чисто виртуальные функции В описании стоит =0; - функция называется чисто

виртуальной (pure virtual). Это значит:

Можно не задавать ее определения

Ее обязательно надо переопределить в одном из производных классов.

10.03.2009 Язык С++ - занятие 4 23

Page 24: Д.з. на  3  марта

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

функция:

Такой класс называется абстрактным (abstract base class)

Нельзя создавать объекты абстрактного класса

shape s; // Ошибка: нельзя создать объект // абстрактного класса

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

10.03.2009 Язык С++ - занятие 4 24

Page 25: Д.з. на  3  марта

Если в документации написано virtual ... = 0;

class abc {virtual void f() = 0;

Это надо читать так: «… Функцию f вы должны переопределить и задать свой вариант. …»

10.03.2009 Язык С++ - занятие 4 25

Page 26: Д.з. на  3  марта

Сложные типы

10.03.2009 Язык С++ - занятие 4 26

Page 27: Д.з. на  3  марта

Как определять сложные типы?

a - массив из 10 укaзателей на int

Массив из 10указателей на int

aa[10]*(a[10])int *(a[10]); // Или int *a[10];

10.03.2009 Язык С++ - занятие 4 27

Page 28: Д.з. на  3  марта

Как читать сложные типы?

int (*a)[10];

а*a(*a)[10]int (*a)[10];

a – этоуказатель намассив из 10 int

10.03.2009 Язык С++ - занятие 4 28

Page 29: Д.з. на  3  марта

typedefСинтаксис:

typedef описание переменной;

typedef unsigned long ulong;

typedef int* my_array[10];

my_array a; // тоже, что int* a[10];

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

void f(unsigned long i){

…}

void f(ulong j) // Ошибка - { // у функций

одинаковые… // параметры

}

10.03.2009 Язык С++ - занятие 4 29

Page 30: Д.з. на  3  марта

Зачем нужен typedef ?1. Сокращенная запись

typedef unsigned long ulong;

2. typedef int MY_INTEGER;

Потом легче менять (encapsulation)

3. Технические причины:

typedef int* pint;pint a[10];

p = new pint[20];

10.03.2009 Язык С++ - занятие 4 30

Page 31: Д.з. на  3  марта

Задачи на 17 марта

10.03.2009 Язык С++ - занятие 4 31

Page 32: Д.з. на  3  марта

Задачи на 17 марта1. a. Определить класс «ромб» (с

диагоналями, параллельными осям координат). Для него определить конструктор и метод draw. (В методе draw вместо рисования можно просто печатать координаты отрезков).

б. Определить какой-нибудь класс, производный от класса «ромб».

2. Написать абстрактный класс shape и производные от него классы rhomb и square. Для этих классов определить конструкторы и методы area (площадь) и perim (периметр). (Метод draw определять не надо).

3. Определить структуру (или класс) «односвязный список». а. Ввести число n и создать список из чисел n, n-1, n-2, … 3, 2, 1.б. Напечатать все числа в списке.

(См. также документ про списки на сайте).

10.03.2009 Язык С++ - занятие 4 32