Технология разработки программного обеспечения систем управления

Объект и класс как основа объектно-ориентированного языка программирования. Методология построения и использования принципов объектно-ориентированного программирования и программирования под Windows на языке C++ при проектировании систем управления.

Рубрика Программирование, компьютеры и кибернетика
Вид учебное пособие
Язык русский
Дата добавления 07.10.2013
Размер файла 744,6 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

33

Министерство образования Республики Беларусь

Учреждение образования «Белорусский государственный университет информатики и радиоэлектроники»

Институт информационных технологий

Кафедра информационных систем и технологий

Лабораторный практикум

для студентов специальности 1-53.01.07 «Информационные технологии и управление в технических системах» всех форм обучения

«технология разработки программного обеспечения систем управления»

С.В. Снисаренко, Н.А. Стасевич, Н.А. Капанов

Минск БГУИР

2011

УДК 004.413:681.51(076.5)

ББК 32.973.26-018.2я73+32.965я73

С 53

Рецензент:

доцент кафедры автоматизации технологических процессов и электротехники учреждения образования «Белорусский государственный технологический университет» И.Ф. Кузьмицкий.

Снисаренко С.В.

С53 Технология разработки программного обеспечения систем управления: лабор. практикум для студ. специальности 1-53.01.07 «Информационные технологии и управление в технических системах» всех форм обучения. / С.В. Снисаренко, Н.А. Стасевич, Н.А. Капанов - Минск: БГУИР, 2011. - с.: ил.

ISBN

Целью настоящего издания является оказание помощи студентам специальности «Информационные технологии и управление в технических системах» при выполнении ими лабораторных работ по курсу «Технология разработки программного обеспечения систем управления».

В практикуме рассматриваются вопросы, относящиеся к использованию технологии объектно-ориентированного программирования и программирования под Windows на языке C++ при проектировании систем управления. Описание методологии построения и использования основных принципов объектно-ориентированного программирования и программирования под Windows сопровождается примерами.

Предназначен для студентов специальности 1-53.01.07 «Информационные технологии и управление в технических системах» всех форм обучения БГУИР.

УДК 004.413:681.51(076.5)

ББК 32.973.26-018.2я73+32.965я73

© Снисаренко С.В., Стасевич Н.А., Капанов Н. А. 2011.

ISBN © УО «Белорусский государственный университет информатики и радиоэлектроники», 2011.

Содержание

Введение

1. Лабораторная работа № 1. Программирование алгоритмов с использованием динамических массивов

2. Лабораторная работа № 2. Классы. Программирование линейных алгоритмов с использованием функций инициализации set() и вывода результатов print()

3. Лабораторная работа № 3. Классы. Программирование линейных алгоритмов с использованием конструктора, деструктора, friend - функции инициализации set() и функции вывода результатов print()

4. Лабораторная работа № 4. Класс «Динамическая строка» и перегрузка операций

5. Лабораторная работа № 5. Наследование классов, механизм виртуальных функций

6. Лабораторная работа № 6. Программирование шаблона классов

7. Лабораторная работа № 7. Множественное наследование с использованием абстрактных базовых классов, файлового ввода - вывода с применением потоков С++, функций обработки исключительных ситуаций

8. Лабораторная работа № 8. Мастера Сlassview и Сlasswizard в Visual C++

9. Лабораторная работа № 9. Интерфейс графических устройств Windows

10.Лабораторная работа № 10. Элементы управления радиокнопки (Radio Button) и переключатели (Check Box)

11. Лабораторная работа №11. Работа с элементом управления «Окно списка» (ListBox)

122. Лабораторная работа №12. Работа с элементом управления «Комбинированный список» (ComboBox)

13. Лабораторная работа №13. Элементы управления «Шкала индикации» (Progress) и «Маркер» (Slider). Модальные диалоговые окна

14. Лабораторная работа №14. MDI - приложение. Работа с данными в архитектуре «Документ/представление» («Document/view»)

Список использованной литературы

Введение

С++ является языком объектно-ориентированного программирования (ООП). Объект - абстрактная сущность, наделенная характеристиками объектов реального мира. Как и любой другой язык ООП, С++ использует три основные идеи ООП - инкапсуляцию, наследование и полиморфизм.

Инкапсуляция - сведение кода и данных воедино в одном объекте, получившим название класс.

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

Полиморфизм - дословный перевод с греческого «много форм». В С++ полиморфизм реализуется с помощью виртуальных функций, которые позволяют в рамках всей иерархии классов иметь несколько версий одной и той же функции. Решение о том, какая именно версия должна выполняться в данный момент, определяется на этапе выполнения программы и носит название позднего связывания.

Существует несколько реализаций системы, поддерживающих стандарт С++, из которых можно выделить реализации Visual C++ (Microsoft) и Builder C++ (Inprise). Отличия относятся в основном к используемым библиотекам классов и средам разработки. В действительности в С++ программах можно использовать библиотеки языка С, библиотеки классов С++, библиотеки визуальных классов VCL (Builder C++), библиотеку MFC (Visual C++ и Builder C++).

Язык С++ является родоначальником множества объектно-ориентированных языков, таких как Java, C#, PHP и др.

Данное издание предназначено для начинающих изучение технологии ООП и программирования под Windows для проектирования систем управления на основе С++.

1. Лабораторная работа № 1. Программирование алгоритмов с использованием динамических массивов

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

· Теоретические сведения

Объявление динамического массива

Массивы, создаваемые в динамической памяти, будем называть динамическими (размерность становится известна в процессе выполнения программы). При описании массива после имени в квадратных скобках задается количество его элементов (размерность), например, int a[10]. Размерность массива может быть задана только константой или константным выражением.

При описании массив можно инициализировать, т. е. присвоить его элементам начальные значения, например:

int а[10] = {1, 1, 2, 2, 5, 100};

Если инициализирующих значений меньше, чем элементов в массиве, остаток массива обнуляется, если больше - лишние значения не используются. Элементы массивов нумеруются с нуля, поэтому максимальный номер элемента всегда на единицу меньше размерности. Номер элемента указывается после его имени в квадратных скобках: например, а[0], а[3].

Если до начала работы программы неизвестно, сколько в массиве элементов, то в программе следует использовать динамические массивы. Память под них выделяется с помощью операции new или функции malloc в динамической области памяти во время выполнения программы. Адрес начала массива хранится в переменной, называемой указателем. Например:

int n = 10;

int *mass1 = new int[n];

Во второй строке описан указатель на целую величину, которому присваивается адрес начала непрерывной области динамической памяти, выделенной с помощью операции new. Выделяется столько памяти, сколько необходимо для хранения n величин типа int. Величина n может быть переменной. Инициализировать динамический массив нельзя.

Обращение к элементу динамического массива осуществляется так же, как и к элементу обычного. Если динамический массив в какой-то момент работы программы перестает быть нужным, и мы собираемся впоследствии использовать эту память повторно, то необходимо освободить ее с помощью операции delete[], например: delete [] a; (размерность массива при этом не указывается).

delete[] mass1.

При необходимости создания многомерных динамических массивов сначала следует с помощью операции new выделить память под n указателей (вектор, элемент которого - указатель), при этом все указатели располагаются в памяти последовательно друг за другом. После этого необходимо в цикле каждому указателю присвоить адрес выделенной области памяти размером, равным второй границе массива:

mass2=new int*[row];

// mass2 - указатель на

// массив //указателей на

// одномерные массивы

for(i=0;i<row;i++)

mass2[i]=new int[col];// каждый элемент массива

// указывает на //одномерный

for (i=0; i<row;i++)

for (j=0;j<col;j++)

Освобождение памяти от двухмерного динамического массива:

for(i=0;i<row;i++)

//удаление всех одномерных

delete[] mass2[i]; // массивов

delete[] mass2;

// удаление массива //указателей

// на одномерные массивы

· Задание к лабораторной работе

Общая постановка. Составить программы - одномерные массивы: задания 1 - 25, двухмерные массивы: задания 26 - 50. Массивы создаются в динамической области памяти с использованием операций NEW и DELETE. Ввод исходных данных: реальный размер массивов и их значения. Обращение к элементам массива - через косвенную адресацию. Действия с массивами реализовать в виде функции.

· Варианты заданий

1. Заданы два массива - А(5) и В(4). Первым на печать вывести массив, сумма значений которого окажется наименьшей.

2. Заданы два массива - А(5) и В(4). Первым на печать вывести массив, произведение значений которого окажется наименьшим.

3. Заданы два массива - А(5) и В(5). В каждом из массивов найти наименьшее значение и прибавить его ко всем элементам массивов. На печать вывести исходные и преобразованные массивы.

4. Заданы два массива - А(5) и В(5). В каждом из массивов найти наибольшее значение и вычесть его из всех элементов массивов. На печать вывести исходные и преобразованные массивы.

5. Заданы два массива - А(5) и В(5). В каждом из массивов найти среднее арифметическое всех элементов массивов. На печать вывести исходные массивы и найденные значения.

6. Заданы два массива - А(5) и В(4). Первым на печать вывести массив, содержащий наибольшее значение. Напечатать также это значение и его порядковый номер.

7. Заданы два массива - А(5) и В(5). Подсчитать в них количество отрицательных элементов и первым на печать вывести массив, имеющий наименьшее их количество.

8. Заданы два массива - А(5) и В(5). Подсчитать в них количество положительных элементов и первым на печать вывести массив, имеющий наименьшее их количество.

9. Заданы два массива - А(5) и В(5). Подсчитать в них количество отрицательных элементов и первым на печать вывести массив, имеющий наибольшее их количество.

10. Заданы два массива - А(5) и В(5). Подсчитать в них количество положительных элементов и первым на печать вывести массив, имеющий наибольшее их количество.

11. Заданы два массива - А(5) и В(5). Подсчитать в них количество элементов, больших значения t, и первым на печать вывести массив, имеющий наименьшее их количество.

12. Заданы два массива - А(5) и В(5). Подсчитать в них количество элементов, меньших значения t, и первым на печать вывести массив, имеющий наименьшее их количество.

13. Заданы два массива - А(5) и В(5). Подсчитать в них количество элементов, больших значения t, и первым на печать вывести массив, имеющий наибольшее их количество.

14. Заданы два массива - А(5) и В(5). В каждом из массивов найти наименьшее значение и умножить на него все элементы массивов. На печать вывести исходные и преобразованные массивы.

15. Заданы два массива - А(5) и В(5). В каждом из массивов найти наибольшее значение и умножить на него все элементы массивов. На печать вывести исходные и преобразованные массивы.

16. Заданы два массива - А(5) и В(5). В каждом из массивов найти наименьшее значение и разделить на него все элементы массивов. На печать вывести исходные и преобразованные массивы.

17. Заданы два массива - А(5) и В(5). В каждом из массивов найти наибольшее значение и разделить на него все элементы массивов. На печать вывести исходные и преобразованные массивы.

18. Заданы два массива - А(5) и В(5). Подсчитать в них количество элементов, кратных двум, и первым на печать вывести массив, имеющий наибольшее их количество.

19. Заданы два массива - А(5) и В(5). Подсчитать в них количество элементов, кратных трем, и первым на печать вывести массив, имеющий наибольшее их количество.

20. Заданы два массива - А(5) и В(5). Подсчитать в них количество элементов, меньших значения t, и первым на печать вывести массив, имеющий наибольшее их количество.

21. Задан массив - А(10). Получить из него массив В, состоящий из элементов массива А, которые больше 0.

22. Задан массив - А(10). Получить из него массив В, состоящий из элементов массива А, которые меньше 0.

23. Задан массив - А(10). Получить из него массив В, состоящий из элементов массива А, которые кратны двум.

24. Задан массив - А(10). Получить из него массив В, состоящий из элементов массива А, которые больше значения T.

25. Задан массив - А(10). Получить из него массив В, состоящий из элементов массива А, которые кратны трем.

26. Дан массив - А(n,n). Найти число элементов массива a(i,j) > t и просуммировать все эти элементы.

27. Дан одномерный массив - А(n). Сформировать массив B(k),состоящий из a(i) > t. На печать вывести исходный массив, сформированный массив и его размерность.

28. Дан массив - A(n,n). Вычислить сумму всех неотрицательных элементов, а также их количество.

29. Дан массив - A(n,n). Вычислить сумму всех отрицательных его элементов и их количество.

30. Дан массив - A(n,n). Сформировать вектор В(k) из a(i,j) < 0. На печать вывести исходный массив, полученный вектор и его размерность.

31. Дан массив - A(n,n). Написать программу его поворота на 90° относительно его центра. На печать вывести исходный и повернутый массивы.

32. Дан массив - A(n,n). Написать программу его поворота на 180° относительно его центра. На печать вывести исходный и повернутый массивы.

33. Дан массив - A(n,n). Написать программу его поворота на 270° относительно его центра. На печать вывести исходный и повернутый массивы.

34. Дан массив - A(n,n). Найти сумму всех его элементов, расположенных выше главной диагонали.

35. Дан массив - A(n,n). Найти сумму всех его элементов, расположенных ниже главной диагонали.

36. Дан массив - A(n,n). Найти сумму всех его элементов, расположенных выше диагонали, противоположной главной.

37. Дан массив - A(n,n). Найти сумму всех его элементов, расположенных ниже диагонали, противоположной главной.

38. Задана матрица - А(n,n). Найти суммы и произведения элементов, стоящих на главной и противоположной (побочной) диагоналях.

39. Задана матрица - А(n,n), состоящая из нулей и единиц. Подсчитать количество нулей и единиц в этой матрице.

40. Задана матрица - А(n,n). Переставить местами k-ю и i-ю строки, а эатем l-й и j-й столбцы.

41. Задан массив действительных чисел А(n). Необходимо каждый элемент массива разделить на среднее арифметическое этих элементов. На печать вывести исходный и преобразованный массивы.

42. Задан массив - А(n). Получить массив В(k), состоящий из элементов массива А, которые делятся на 3. Подсчитать количество элементов массива В.

43. Задана матрица А(n,n). Получить матрицу В=А^2. Элемент b[I][j] определяется как сумма от поэлементного произведения i-й строки на j-й столбец матрицы А.

44. Вычислить первую норму матрицы А(n,n), определяемую как , т.е. максимальная сумма из сумм элементов по столбцам.

45. Вычислить вторую норму матрицы А(n,n), определяемую как максимальная сумма из сумм элементов по строкам .

46. Задан двухмерный массив целых чисел A размером N на M. Найти сумму элементов, расположенных на главной диагонали.

47. Задан двухмерный массив целых чисел A размером N на M. Найти произведение элементов, расположенных на главной диагонали.

48. Задан двухмерный массив целых чисел A размером N на M. Найти максимальный элемент и поменять его с элементом A[1,1].

49. Задан двухмерный массив целых чисел A размером N на M. Найти минимальный элемент и поменять его с элементом A[1,1].

50. Задан двухмерный массив целых чисел A размером N на M. Найти максимальный элемент и поменять его с последним.

· Контрольные вопросы

1. В чем заключается особенность динамических массивов?

2. Какие вы знаете операции динамического выделения и освобождения памяти в С++?

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

4. Что содержит указатель на массив?

2. Лабораторная работа № 2. Классы. Программирование линейных алгоритмов с использованием функций инициализации set() и вывода результатов print()

Цель работы - изучить основные способы работы с пользовательским типом данных «класс», его объектами, методами и способы доступа к ним.

· Теоретические сведения

Основное отличие С++ от С состоит в том, что в С++ имеются классы. С точки зрения языка С классы в С++ - это структуры, в которых вместе с данными определяются функции. Это и есть инкапсуляция в терминах ООП.

Класс (class) - это тип, определяемый пользователем, включающий в себя данные и функции, называемые методами или функциями-членами класса.

Данные класса - это то, что класс «знает».

Функции - члены (методы) класса - это то, что класс «делает».

Таким образом, определение типа, задаваемого пользователем (class), содержит спецификацию данных, требующихся для представления объекта этого типа, и набор операций (функций) для работы с подобными объектами.

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

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

class my_Fun

{

// компоненты-данные

double x,y;

// компоненты-функции

public:

// функция инициализации

void set(char *c,double X)

{

x=X;

y=sin(x);

}

// функция вывода результатов

void print(void)

{

cout << point<<y << endl;

}

};

Обычно описания классов включают в заголовочные файлы (*.H), а реализацию функций-членов классов - в файлы *.CPP.

Для каждого объекта класса устанавливается область видимости либо явно - указанием уровня доступа одним из ключевых слов public, private, protected с двоеточием, либо неявно - по умолчанию. Указание области видимости относится ко всем последующим объектам класса, пока не встретится указание другой области видимости. Область видимости public разрешает доступ к объектам класса из любой части программы, в которой известен этот объект (общедоступный). Область видимости private разрешает доступ к объектам класса только из методов этого класса. Объекты с такой областью видимости называют частными. Область видимости protected определяется для защищенных объектов, она имеет смысл только в иерархической системе классов и разрешает доступ к объектам этой области из методов производных классов. В теле класса ключевое слово области видимости может использоваться неоднократно. Область видимости для объектов типа «класс» по умолчанию private.

Способы объявления и инициализации объектов и доступ к методам класса:

1. Прямой вызов

my_Fun Fun1;//объявление объекта1,но не инициализация

Fun1.set("Function1 = ",1.0);// инициализация данных

Fun1.print(); // прямой вызов

cout << "Input enter1..." << endl<<endl.

2. Косвенный вызов

my_Fun *p1 = &Fun1; // воспользовались объектом 1

// новая инициализация

p1->set("Function1 = ",1.0); // косвенный вызов

p1->print();

// косвенный вызов

cout << "Input enter1..." << endl<<endl;

3 Динамическое выделение памяти

my_Fun *p1 = new my_Fun;

p1->set("Function1 = ",1.0); // косвенный вызов

p1->print();

// косвенный вызов

cout << "Input enter1..." << endl<<endl;

// удаляется динамически выделенный объект

delete p1;

· Задание к лабораторной работе

Пользовательский класс должен содержать необходимые элементы - данные, метод установки их начальных значений:

Void set(double X,);

метод печати:

Void print(void);

метод, решающий поставленную задачу:

Void Run(void);

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

· Варианты заданий

1.

При x=14,26, y= -1,22, z=3,5ґ, t=0,564849.

2.

При x= -4,5, y=0,75ґ, z=0,845, u=-55,6848.

3.

При x=3,74, y= -0,825, z=0,16, v=1,0553.

4.

При x=0,4, y= -0.875, z= -0,475, w=1,9873.

5.

При x= -15,246, y=4,642, z=20.001, = -182.036.

6.

7. При x=16,55, y= -2,75, z=0,15, = - 40,630.

8.

При x=0,1722, y=6,33, z=3,25, = -205,305.

9.

При x= -2,235, y=2,23, z=15,221, =39,374.

10.

При x=1,825, y=18,225, z= -3,298, =1,2131.

11.

При x=6,251, y=0,827, z=25,001, b=0,7121.

12.

При x=3,251, y=0,325, z=0,466, c = 4,25.

13.

При x=17,421, y=10,365, z=0,828, f=0,33056.

14.

При x=12,3, y=15,4, z=0,252, g=82,8257.

15.

При x=2,444, y=0,869, z= -0,13, -0,49871.

Контрольные вопросы

1. Что значит в ООП понятие «класс», и какой формат его объявления в программе?

2. Что такое объект класса, что он содержит?

3. Какие существуют уровни доступа к объектам и методам класса? (Дать характеристику каждому).

4. Что такое операция привязки, ее основное назначение?

3. Лабораторная работа 3. Классы. Программирование линейных алгоритмов с использованием конструктора, деструктора, friend - функции инициализации set() и функции вывода результатов print()

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

Теоретические сведения

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

Конструктор - это метод класса, имя которого совпадает с именем класса. Конструктор вызывается автоматически после выделения памяти для переменной и обеспечивает инициализацию данных. Конструктор не имеет никакого типа (даже типа void) и не возвращает никакого значения в результате своей работы. Конструктор нельзя вызывать как обычную компонентную функцию в программе. Для класса может быть объявлено несколько конструкторов, различающихся числом и типами параметров. При этом, даже если для объектного типа не определено ни одного конструктора, компилятор создает для него конструктор по умолчанию, не использующий параметров, а также конструктор копирования, необходимый в том случае, если переменная объектного типа передается в конструктор как аргумент. В этом случае создаваемый объект будет точной копией аргумента конструктора.

class my_Fun

{

// компоненты-данные

double x;

unsigned size;

public:

// объявление конструктора 1 (с параметрами)

my_Fun (double X=0);

// объявление конструктора 2 (без параметров)

my_Fun(void);

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

~my_Fun ()

{

cout<<"Destroyed object... "<<endl;

}

// описание конструктора 1

my_Fun::my_Fun (double X)

{

cout<<"Constructor1...."<<endl;

x=X;

}

// описание конструктора 2

my_Fun::my_Fun (void)

{

cout<<"Constructor2..."<<endl;

x=5.0;

}

}

Деструктор класса

Еще одним специальным методом класса является деструктор. Деструктор вызывается перед освобождением памяти, занимаемой объектной переменной, и предназначен для выполнения дополнительных действий, связанных с уничтожением объектной переменной: например, для освобождения динамической памяти, закрытия, уничтожения файлов и т.п. Деструктор всегда имеет то же имя, что и имя класса, но перед именем записывается знак ~ (тильда). Деструктор не имеет параметров и, подобно конструктору не возвращает никакого значения.

Таким образом, деструктор не может быть перегружен и должен существовать в классе в единственном экземпляре. Деструктор вызывается автоматически при уничтожении объекта. Таким образом, для статически определенных объектов деструктор вызывается, когда заканчивается блок программы, в котором определен объект (блок в данном случае - составной оператор или тело функции). Для объектов, память для которых выделена динамически, деструктор вызывается при уничтожении объекта операцией delete.

Дружественная функция (friend)

В языке С++ одна и та же функция не может быть компонентом двух разных классов. Чтобы предоставить функции возможность выполнения действий над различными классами, можно определить обычную функцию языка С++ и предоставить ей право доступа к элементам класса типа private, protected. Для этого нужно в описании класса поместить заголовок функции, перед которым поставить ключевое слово friend.

Дружественная функция не является методом класса, не зависит от позиции в классе и спецификаторов прав доступа. Friend - функции получают доступ к членам класса через указатель, передаваемый им явно. Можно сделать все функции класса Y друзьями класса X в одном объявлении.

· Задание к лабораторной работе

Общая постановка. Пользовательский класс Х должен содержать необходимые элементы - данные, которые создаются в динамической области памяти, конструктор для их создания (операция new) и установки их начальных значений: Х(), деструктор: ~ Х (), friend - функция печати: friend void print(), функция, решающая поставленную задачу: friend Void Run().

Код методов и функций - вне пространства определения класса.

· Варианты заданий

Варианты заданий используются из лабораторной работы № 2.

· Контрольные вопросы

1. Что такое «конструктор», формат объявления, его особенности?

2. Формат объявления деструктора, его назначение.

3. Особенности дружественных функций, доступ к закрытой части класса.

4. Каким образом дружественная функция получает доступ к закрытой части класса?

4. Лабораторная работа 4. Класс «Динамическая строка» и перегрузка операций

объект ориентированный класс программирование

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

· Теоретические сведения

Для представления символьной (текстовой) информации можно использовать символы, символьные переменные и символьные константы.

Символьная константа представляется последовательностью символов, заключенной в кавычки: «Начало строки \n». В С++ нет отдельного типа для строк. Массив символов - это и есть строка. Количество элементов в таком массиве на один элемент больше, чем изображение строки, т. к. в конец строки добавлен `\0' (нулевой байт).

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

char s[] = “ABCDEF”.

Для работы со строками существует специальная библиотека string.h. Примеры функций для работы со строками из библиотеки string.h приведены в таблице 2.

Таблица 2 - Функции работы со строками

Функция

Прототип и краткое описание функции

strcmp

int strcmp(const char *str1, const char *str2);

Сравнивает строки str1 и str2. Если str1 < str2, то результат отрицательный, если str1 = str2, то результат равен 0, если str1> str2, то результат положительный.

strcpy

char* strcpy(char*s1, const char *s2);

Копирует байты из строки s1 в строку s2.

strdup

char *strdup (const char *str);

Выделяет память и переносит в нее копию строки str.

strlen

unsigned strlen (const char *str);

Вычисляет длину строки str.

strncat

char *strncat(char *s1, const char *s2, int kol);

Приписывает kol символов строки s1 к строке s2.

strncpy

char *strncpy(char *s1, const char *s2, int kol);

Копирует kol символов строки s1 в строку s2.

strnset

char *strnset(char *str, int c, int kol);

Заменяет первые kol символов строки s1 символом с.

Строки при передаче в функцию в качестве фактических параметров могут быть определены либо как одномерные массивы типа char[], либо как указатели типа char*. В отличие от обычных массивов, в этом случае нет необходимости явно указывать длину строки.

Функции преобразования строки S в число:

целое: int atoi(S);

длинное целое: long atol(S);

действительное: double atof(S),при ошибке возвращает значение 0.

Функции преобразования числа V в строку S:

целое: itoa(int V,char S,int kod);

длинное целое: ltoa(long V,char S,int kod); 2<=kod<=36, для отрицательных чисел kod=10.

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

Для перегрузки операции для класса в С++ используется следующий синтаксис:

<Тип> operator <операция>(<входные параметры>)

{

<операторы>;

}

где < Тип > - тип, возвращаемый функцией;

operator - ключевое слово;

< операция > - перегружаемая операция.

В языке С++ имеются следующие ограничения на перегрузку операций:

- С++ не различает префиксную и постфиксную формы ++ и - -;

- переопределяемая операция должна присутствовать в языке (например, нельзя определить операцию с символом #);

- нельзя переопределить операторы, заданные следующими символами: * :: ? ;

- переопределенные операции сохраняют свой изначальный приоритет.

Наличие в классе конструктора String:: String(String&) и операторов присваивания позволяет защитить объекты класса от побитового копирования.

Файловые потоки. Классы файловых потоков:

ifstream - файл ввода, производный от istream,

ofstream - файл вывода, производный от ostream,

fstream - файл ввода-вывода, производный от iostream.

Флаги режимов работы с файлом:

enum ios::open_mode

{

in = 0x01, // Открыть файл только для чтения

out = 0x02, // Открыть файл только для записи

ate = 0x04, // При открытии позиционироваться в конец файла

app = 0x08, // Открыть существующий для дополнения

trunc = 0x10, // Создание нового файла взамен существующего

nocreate=0x20, // Не создавать новый файл при его отсутствии

noreplace=0x40, // Не создавать новый файл, если он существует

binary= 0x80 // Двоичный файл ("прозрачный" ввод-вывод без // преобразования символов конца строки)

}

Конструкторы объектов (для классов ifstream,ofstream,fstream) и функции открытия/закрытия файлов:

ifstream(); // Без открытия файлов

ifstream( // С открытием файла в заданном

char *name, // режиме imode

int imode=ios::in,

int prot=filebuf::openprot);

ifstream(int fd); // С присоединением файла с дескриптором fd

ifstream (// То же, с явно заданным буфером

int fd,

char *buf, int sz);

void ifstream::open

char *name, // Открытие файла в заданном режиме

int imode=ios::in,

int prot=filebuf::openprot);

void close(); // Закрыть файл

void setbuf(

char *p,int sz);// Установить буфер потока

int fd(); // Дескриптор открытого в потоке файла

int is_rtl_open(); // 1 - файл открыт в потоке

Унаследованные переопределения операторов позволяют проверять наличие ошибок в потоках в виде:

fstream ss;

if (ss) ... или if (!ss).

· Задание к лабораторной работе

Общая постановка. Пользовательский класс String должен содержать необходимые элементы-данные, которые создаются в динамической области памяти.

Конструктор для создания строк: String (…);

Деструктор: ~String();

Метод ввода исходной строки: Set();

Метод печати: void print(…);

Код методов - вне пространства определения класса. Программа иллюстрирует прямой и косвенный способы обращения к методам.

Ввести с клавиатуры строку символов S1. Признак окончания ввода строки - нажатие клавиши «Ввод». Программа должна содержать перегруженную операцию «=», использование которой скопирует S1 в S2 .

Исходную и преобразованную строки вывести в файл.

· Варианты заданий

1. Если длина L нечетная, то удаляется символ, стоящий посередине строки.

2. Если длина L четная, то удаляются 2 первых и 2 последних символа.

3. Если длина L кратна 2, то удаляются все числа, которые делятся на 2.

4. Если длина L кратна 3, то удаляются все числа, делящиеся на 3.

5. Если длина L >10, то удаляются все цифры.

6. Если длина L >15, то удаляются все a..z.

7. Если длина L=10, то удаляются все A..Z.

8. Если длина L кратна 4, то первая часть строки меняется местами со

второй.

9. Если длина L кратна 5, то подсчитывается количество скобок всех

видов.

10. Если длина L >5, то выделяется подстрока до первого пробела.

11. Если длина L >6, то выделяется подстрока { } скобках.

12. Если длина L >10, то удаляется подстрока в [] скобках.

13. Если длина L >12, то удаляется подстрока до первой открывающейся скобки.

14. Если длина L кратна 4, то выделяется подстрока после последнего

пробела.

15. Если длина L >5, то удаляются все точки.

16. Если длина L четная, то выделяется подстрока до первого пробела.

17. Если длина L четная, то удаляется подстрока до первого пробела.

18. Если длина L четная, то выделяется подстрока со второго пробела.

19. Если длина L нечетная, то выделяется подстрока после первого пробела.

20. Если длина L нечетная, то удаляется подстрока со второго пробела.

21. Если длина L кратна 3, то удаляется каждый 3-й символ.

22. Если длина L четная, то удаляется каждый 2-й символ.

23. Если длина L нечетная, то удалить средние 3 символа.

24. Если длина L четная, то выделяется подстрока до последнего пробела.

25. Если длина L нечетная, то выделяется подстрока от последней цифры.

26. Если длина L=15, то удаляются все символы кроме A - Z.

27. Если длина L делится на 5, то удаляется все символы кроме a - z.

28. Если длина L четная и >=10, то удаляются все пробелы.

29. Если длина L нечетная и <12, произвести инверсию (abcdef в fedcba).

30. Если длина L >5 и <30, изменить регистр символов (aBcDeF в AbCdEf).

· Контрольные вопросы

1. Как объявить динамическую строку в С++?

2. Какие вы знаете функции работы со строками?

3. Как определяются строки при передаче в функцию в качестве фактических параметров?

4. Поясните механизм перегрузки операций для объектов данного класса.

5. Лабораторная работа № 5. Наследование классов, механизм виртуальных функций

Цель работы - изучить одну из базовых концепций ООП, наследование классов в С++, заключающуюся в построении цепочек классов, связанных иерархически, познакомиться с механизмом виртуальных функций.

· Теоретические сведения

Наследование - механизм создания производного класса из базового, т.е. к существующему классу можно что-либо добавить или изменять его каким-либо образом для создания нового (производного) класса. Это мощный механизм для повторного использования кода. Наследование позволяет создавать иерархию связанных типов, совместно использующих код и интерфейс. Модификатор прав доступа используется для изменения доступа к наследуемым объектам в соответствии с правилами, указанными в таблице 1.

Таблица 1 - Доступ в классах при наследовании

Доступ в базовом классе

Модификатор прав доступа

Доступ в производном классе

private

private

не доступны

private

public

не доступны

protected

private

private

protected

public

protected

public

private

private

public

public

public

Ограничение на наследование

При определении производного класса не наследуются из базового:

1) конструкторы;

2) деструкторы;

3) операторы new, определенные пользователем;

4) операторы присвоения, определенные пользователем;

5) отношения дружественности.

Использование косвенной адресации с установкой указателей на базовый класс. Механизм косвенной адресации рассмотрим на примере:

class B

{

public:

int x;

B() { // Конструктор по умолчанию

x = 4; }

};

class D : public B

{

// Производный класс

public:

int y;

D()

{// Конструктор по умолчанию

y = 5; }

};

void main(void) {

D d;// Конструктор класса D создает объект d

B *p; // Указатель установлен на базовый касс

p = &d;// Указатель p инициализируется адресом d

// косвенное обращение к объектам базового и производного классов

// «считываем их текущее состояние в переменные

int i = p -> x; // Базовый класс виден напрямую

int j = ( ( D* ) p )p -> y;// Прямое преобразование указателя на D

// через переменные печатаем их текущее состояние

cout << “ x_i= “ << i << endl;

cout << “ y_j= “ << j << endl;

getch();

}

Виртуальная функция и механизм позднего связывания

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

Обычную функцию-метод можно переопределить в наследуемых классах. Однако без атрибута virtual такая функция-метод будет связана с сообщением на этапе компиляции. Атрибут virtual гарантирует позднее связывание в пределах полиморфического кластера.

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

С++ поддерживает virtual функции-методы, которые объявлены в основном классе и переопределены в порожденном классе. Иерархия классов, определенная общим наследованием, создает связанный набор типов пользователя, на которые можно ссылаться с помощью указателя базового класса. При обращении к виртуальной функции через этот указатель в С++ выбирается соответствующее функциональное определение во время выполнения. Объект, на который указывается, должен содержать в себе информацию о типе, поскольку различие между ними может быть создано динамически. Эта особенность типична для ООП - кода. Каждый объект «знает» как на него должны воздействовать. Эта форма полиморфизма называется чистым полиморфизмом.

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

· Задание к лабораторной работе

Общая постановка. Программа должна содержать:

- базовый класс Х, включающий два элемента х1, х2 типа int,

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

деструктор,

- виртуальные методы просмотра текущего состояния и переустановки объектов базового класса в новое состояние.

- производный класс У, включающий один элемент у типа int;

- конструктор с параметрами и списком инициализаторов, передающий данные конструктору базового класса,

- переопределенные методы просмотра текущего состояния объектов и их переустановки в новое состояние.

· Варианты заданий

Создать в производном классе метод Run, определяющий:

Сумму переменных классов.

Произведение переменных классов.

Сумму квадратов переменных классов.

Значение х1+х2 - у.

Значение (х1+х2)/у.

Значение (х1+х2)*у.

Значение х1*у+х2.

Значение х1+х2*у.

Произведение квадратов переменных класса.

Значение х1*х2+у.

Значение х1*х2/у.

Значение х1*х2-у.

Значение (x1-x2)*y.

Значение (x1-x2)/y.

· Контрольные вопросы

1. Что такое наследование, одиночное наследование, множественное наследование?

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

3. На примере своей программы поясните механизм позднего связывания.

4. В каком случае С++ проигнорирует механизм виртуальных функций?

6. Лабораторная работа № 6. Программирование шаблона классов

Цель работы - изучить приемы создания и использования шаблонов классов.

· Теоретические сведения

Достаточно часто встречаются классы, объекты которых должны содержать элементы данных произвольного типа (в том смысле, что их тип определяется отдельно для каждого конкретного объекта). В качестве примера можно привести любую структуру данных (массив указателей, список, дерево). Для этого в С++ предлагаются средства, позволяющие определить некоторое множество идентичных классов с параметризованным типом внутренних элементов. Они представляют собой особого вида заготовку класса, в которой в виде параметра задан тип (класс) входящих в него внутренних элементов данных. При создании конкретного объекта необходимо дополнительно указать и конкретный тип внутренних элементов в качестве фактического параметра. Создание объекта сопровождается созданием соответствующего конкретного класса для типа, заданного в виде параметра. Принятый в С++ способ определения множества классов с параметризованным внутренним типом данных (иначе - макроопределение) называется шаблоном (template).

Синтаксис шаблона рассмотрим на примере шаблона класса векторов, содержащих динамический массив указателей на переменные заданного типа.

// <class T> - параметр шаблона - класс "T", внутренний тип данных

// vector - имя группы шаблонных классов

template <class T> class vector

{

int tsize; // Общее количество элементов

int csize; // Текущее количество элементов

T **obj; // Массив указателей на параметризованные //объекты типа "T"

public:

T *operator[](int); // оператор [int] возвращает указатель на

// параметризованный объект класса "T"

void insert(T*); // включение указателя на объект типа "T"

int index(T*);

};

Данный шаблон может использоваться для порождения объектов-векторов, каждый из которых хранит объекты определенного типа. Имя класса при этом составляется из имени шаблона "vector" и имени типа данных (класса), который подставляется вместо параметра "Т":

vector<int> a;

vector<double> b;

extern class time;

vector<time> c;

Заметим, что транслятором при определении каждого вектора с новым типом объектов генерируется описание нового класса по заданному шаблону (естественно, неявно в процессе трансляции). Например, для типа int транслятор получит:

class vector<int>

{

int tsize;

int csize;

int **obj;

public:

int *operator[](int);

void insert(int*);

int index(int*);

};

Далее следует очевидное утверждение, что функции - методы шаблона также должны быть параметризованы, т. е. генерироваться для каждого нового типа данных. Действительно, это так: функции-методы шаблона классов, в свою очередь, также являются шаблонными функциями с тем же параметром. То же самое касается переопределяемых операторов:

// параметр шаблона - класс "T", внутренний тип данных

// имя функции-элемента или оператора - параметризовано

//

template <class T> T* vector<T>::operator[](int n)

{

if (n >=tsize) return(NULL);

return (obj[n]);

}

template <class T> int vector<T>::index(T *pobj)

{

int n;

for (n=0; n<tsize; n++)

if (pobj == obj[n]) return(n);

return(-1);

}

Заметим, что транслятором при определении каждого вектора с новым типом объектов генерируется набор методов - функций по заданным шаблонам (естественно, неявно в процессе трансляции). При этом сами шаблонные функции должны размещаться в том же заголовочном файле, где размещается определение шаблона самого класса. Для типа int сгенерированные транслятором функции-методы будут выглядеть так:

int* vector<int>::operator[](int n)

{

if (n >=tsize) return(NULL);

return (obj[n]);

}

int vector<int>::index(int *pobj)

{

int n;

for (n=0; n<tsize; n++)

if (pobj == obj[n]) return(n);

return(-1);

}

· Задание к лабораторной работе

Общая постановка.

Даны: число N и последовательность a1, a2, … aN. Создать шаблон класса, порождающий динамические одномерные массивы с элементами различных типов (вещественные, целочисленные, символьные). Тип данных и результат являются параметрами по отношению к классу, программа должна иметь методы инициализации, конструктор, деструктор, метод просмотра значений созданного массива согласно заданному алгоритму.

Для реализации шаблона использовать библиотеку STL.

· Варианты заданий

1. a1, (a1+a2), … ,(a1+a2+…+aN);

2. (a1*a1), (a1*a2), …, (a1*aN);

3. |a1|, |a1+a2|, …, |a1+a2+…aN|;

4. a1, -a1*a2, +a1*a2*a3, … ,(-1)N*a1*a2*…aN;

5. -a1, +a2, -a3, … , (-1)N*aN;

6. (a1+1), (a2+2) , (a3+3), …, (aN+N);

7. a1*1, a2*2, a3*3, …, aN*N;

8. a1*a2, a2*a3, … , aN-1*aN;

9. a1/1, a2/2, a3/3, … ,aN/N;

10. (a1+a2), (a2+a3), … ,(aN-1+aN);

11. (a1+a2+a3), (a2+a3+a4), (a3+a4+a5), … (aN-2+aN-1+aN);

12. (N+a1), ( N-1+a2), … ,(1+aN);

13. (N*a1), ( (N-1)*a2), … ,(1*aN);

14. a1/N, a2/N, … ,aN/1.

· Контрольные вопросы

1. С какой целью используются шаблоны классов?

2. Какие существуют виды параметров шаблона класса?

3. В чем заключается особенность использования функций - методов шаблона?

4. Может ли использоваться шаблон для параметризованных объектов?

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

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

· Теоретические сведения

Абстрактные классы

Если базовый класс используется только для порождения производных классов, то виртуальные функции в базовом классе могут быть «пустыми», поскольку никогда не будут вызваны для объекта базового класса. Базовый класс, в котором есть хотя бы одна такая функция, называется абстрактным. Виртуальные функции в определении класса обозначаются следующим образом:

classbase

{

public:

virtual print()=0;

virtual get() =0;

};

Определять тела этих функций не требуется.

Множественное наследование

Множественным наследованием называется процесс создания производного класса из двух и более базовых. В этом случае производный класс наследует данные и функции всех своих базовых предшественников. Существенным для реализации множественного наследования является то, что адреса объектов второго и последующих базовых классов не совпадают с адресом объекта производного класса. Этот факт должен учитываться транслятором при преобразовании указателя на производный класс в указатель на базовый и наоборот:

class d : public a,public b, public c { };

d D1;

pd = &D1; // #define dbsizeof(a)

pa = pd; // #define dc sizeof(a)+sizeof(b)

pb = pd; // pb = (char*)pd + db

pc = pd; // pc = (char*)pd + dc

Размещено на http://www.allbest.ru/

33

Такое действие выполняется компилятором как явно, при преобразовании в программе типов указателей, так и неявно, когда в объекте производного класса наследуется функция из второго и последующих базовых классов. Для вышеуказанного примера при определении в классе bb функции f() и ее наследовании в классе "d" вызов D1.f() будет реализован следующим образом:

this = &D1; // Указатель на объект производного класса

this = (char*)this + db // Смещение к объекту базового класса

b::f(this); // Вызов функции в базовом классе

Механизм виртуальных функций при множественном наследовании имеет свои особенности.

Во-первых, на каждый базовый класс в производном классе создается свой массив виртуальных функций (в нашем случае - для aa в d, для bb в d и для ccв d).

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

Файловые потоки. Классы файловых потоков:

ifstream - файл ввода, производный от istream,

ofstream - файл вывода, производный от ostream,

fstream - файл ввода-вывода, производный от iostream.

Флаги режимов работы с файлом:

enum ios::open_mode

{

in = 0x01, // Открыть файл только для чтения

out = 0x02, // Открыть файл только для записи

ate = 0x04, // При открытии позиционироваться в конец файла


Подобные документы

  • Использование объектно-ориентированного программирования - хорошее решение при разработке крупных программных проектов. Объект и класс как основа объектно-ориентированного языка. Понятие объектно-ориентированных языков. Языки и программное окружение.

    контрольная работа [60,1 K], добавлен 17.01.2011

  • Исследование принципов объектно-ориентированного программирования на базе языка программирования С++. Разработка программного комплекса для ведения учёта памятников города. Описание процессов сортировки, поиска, формирования статистики по памятникам.

    курсовая работа [782,4 K], добавлен 26.05.2014

  • Понятие объектно-ориентированного программирования, характеристика используемых языков. Практическая разработка средств объектно-ориентированного программирования в задачах защиты информации: программная реализация на языке С++, а также Turbo Pascal.

    курсовая работа [275,9 K], добавлен 22.12.2011

  • Концепция объектно-ориентированного программирования. Объектно-ориентированные языки программирования: Smalltalk, Object Pascal, CLOS и C++. Понятие "Объект" и "Класс". Управление доступом к элементам данных классов. Определение функций-членов класса.

    реферат [24,5 K], добавлен 28.10.2011

  • Характеристика объектно-ориентированного, процедурного, функционального программирования. Выбор языка программирования для создания программного обеспечения для управления справочником "Спортсмены". Алгоритм работы приложения, пользовательский интерфейс.

    курсовая работа [1,6 M], добавлен 23.02.2016

  • Приемы и правила объектно-ориентированного программирования с использованием языка С++. Общие принципы разработки объектно-ориентированных программ. Основные конструкции языка С++. Разработка различных программ для Windows с использованием WIN32 API.

    учебное пособие [1,6 M], добавлен 28.12.2013

  • Использование скриптового языка программирования для разработки web-приложений (сценариев). Изучение основ объектно-ориентированного программирования в языке PHP. Ознакомление со специальными методами для работы с классами. Назначение интерфейсов.

    контрольная работа [25,1 K], добавлен 14.03.2015

  • Анализ объектно-ориентированного программирования, имитирующего способы выполнения предметов. Основные принципы объектно-ориентированного программирования: инкапсуляция, наследование, полиморфизм. Понятие классов, полей, методов, сообщений, событий.

    контрольная работа [51,7 K], добавлен 22.01.2013

  • Анализ методов объектно-ориентированного программирования на примере численных. Детальная характеристика модулей и связь их в одну общую программу. Принципы интегрирования по общей формуле трапеции и решение дифференциального уравнения методом Эйлера.

    курсовая работа [511,6 K], добавлен 25.03.2015

  • Характеристика основных принципов объектно-ориентированного программирования. Этапы разработки программы на языке C++, реализующей игру "Морской бой". Выбор языка программирования. Характеристика необходимых классов, наследований, виртуальных методов.

    курсовая работа [657,6 K], добавлен 17.06.2012

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.