Методические рекомендации к лабораторной работе №1 на тему Программирование на языке С++ с использованием классов
« НазадМетодические рекомендации к лабораторной работе №1
с курса Програмирование (язык программирование С)
на тему: Программирование на языке С++ с использованием классов
Цель работы: 1) изучить возможности программирования классов на языке С++; 2) получить основные навыки программирования манипуляторов ввода/вывода.
Теоретические сведения
Класс есть расширение понятия структуры языка С++. Он позволяет создавать типы и определять функции, которые задают поведение типа. Каждый представитель класса называется объектом.
Определение класса
Определение класса идентично определению структуры в С++, за исключением того, что:
- оно обычно содержит одну или несколько спецификаций доступа (public, protected, private);
- вместо ключевого слова struct используется слово class;
- оно обычно включает в себя функции (функции-элементы или методы) наряду с данными-элементами;
- обычно в нем имеются некоторые специальные функции, такие как конструктор (функция с тем же именем, что и сам класс) и деструктор (функция, именем которой является имя класса с префиксом - тильдой (~)).
Пример 1. Определение класса.
class str
{ char *s; //элемент-данное
public: //спецификатор открытого доступа
str(char *word); //функция-элемент: конструктор
~str(); //функция-элемент: деструктор
void write(); //функция-элемент: метод печати
};
Управление доступом
В С++ можно ограничить видимость данных и функций класса при помощи меток public, protected, private. Метка-спецификатор доступа применяется ко всем элементам класса, следующим за ней, пока не встретится другая метка или кончится определение класса.
Метка-спецификатор public (открытый) используется тогда, когда элементы-данные и функции-элементы класса должны быть доступны для функций-элементов и других функций программы, в которой имеется представитель класса.
Метка-спецификатор protected (защищенный) используется в том случае, когда элементы данных и функции-элементы должны быть доступны для функций-элементов данного класса и классов производных от него.
Метка-спецификатор private (закрытый) используется, если элементы-данные и функции-элементы должны быть доступны только для функций-элементов данного класса.
В классе элементы по умолчанию являются закрытыми.
Элементы класса
Элементы класса делятся на две основные категории:
- данные, называемые элементами-данными;
- код, называемый элементами-функциями или методами.
Данные-элементы
Данные-элементы классов С++ идентичны элементам структур языка С++ с некоторыми дополнениями:
- данными-элементами могут быть перечислимые типы, битовые поля или представители ранее объявленного класса. Также допускается вложенное объявление перечислимого типа данных и создание псевдонимов с помощью typedef;
- данное-элемент класса может быть указателем или ссылкой на представитель этого класса.
Элементы-функции
Функция-элемент является функцией, объявленной (описанной) внутри определения класса. Тело функции может также определяться внутри определения класса, в этом случае функция называется встроенной (inline) функцией-элементом. Когда тело функции определяется вне тела класса, перед именем функции ставится префикс из имени класса и операции разрешения видимости (::).
Пример 2.
class str
{ char *s; // указатель на строку
public:
str(char *word) // встроенный конструктор
{ s=new char[strlen(word)+1];
strcpy(s, word);
};
~str()
{ delete [ ]s; }; // встроенный деструктор
void write(); // объявление функции-элемента
};
void str::write() // определение функции-элемента
{ cout<<s);
};
Доступ к данным-элементам
Функции-элементы находятся в области действия класса, в котором они определены. Т.о. они могут обращаться к любому элементу класса, используя просто имя переменной. Обычные функции или функции-элементы другого класса могут получить доступ к элементам-данным с помощью операции. или −>, применяемых к представителю или указателю на представитель класса.
Пример 3.
class coord
{ public: int x, y; // координаты x и y
};
void main()
{ coord org; // представитель класса координат
coord *orgptr = &org; // указатель на представитель класса
org.x = 0; // задание значения координаты x
orgptr−>y = 0; // задание значения координаты y
}
Вызов функций-элементов
Функции-элементы класса могут вызывать другие функции-элементы того же класса, используя имя функции.
Пример 4.
class coord
{ int x, y; // координаты x и y
public:
void setcoord(int _x, int _y)
// функция задания значений координат
{ x =_x; y =_y;
};
void getcoord(int &_x, int &_y)
//функция получения значений координат
{_x = x; _y = y;};
};
void main()
{ coord org; // представитель класса координат
coord *orgptr = &org; // указатель на представитель класса
org.setcoord(10, 10); // вызов функции-элемента
// задания значений
int col, row;
orgptr−>getcoord(col, row); // вызов функции-элемента
// получения значений координат
}
Указатель this
Каждая нестатическая (не имеющая спецификатора static) функция-элемент имеет доступ к объекту, для которого вызвана, через ключевое слово this. Указатель this является указателем на тип_класса *.
Пример 5.
class simple
{ public:
simple();
void greet() { cout<<“ Hello!”;};
};
simple::simple()
{ greet(); // вызов
this−>greet(); // функции
(*this).greet(); // greet()
}
Т.к. функции-элементы могут обращаться ко всем элементам класса просто по имени, в основном указатель this используется для возвращения указателя (return this) или ссылки (return *this) на подразумеваемый объект.
Конструктор
Конструктор инициализирует представитель класса (объект) и является функцией-элементом с тем же именем, что и класс. Конструктор вызывается компилятором всегда, когда создается представитель класса. Объект считается созданным в тот момент, когда завершил работу конструктор объекта.
Для конструкторов выполняются следующие правила:
- для конструктора не указывается возвращаемый тип;
- конструктор не может возвращать значение;
- конструктор не наследуется;
- для одного класса может существовать один или несколько конструкторов;
- если конструктор не задан явным образом, то автоматически создаётся пустой конструктор.
Деструктор
Деструктор является дополнением конструктора. Он имеет то же имя, что и класс, но с префиксом - тильдой (~). Он вызывается всякий раз, когда уничтожается представитель класса. Объект считается уничтоженным, когда завершил работу деструктор объекта. Для деструктора существуют следующие правила:
- деструктор не может иметь аргументов;
- деструктор не может возвращать значения;
- деструктор не наследуется (исключением является виртуальный деструктор);
- для одного класса может существовать только один деструктор;
- если деструктор не задан явным образом, то автоматически создаётся пустой деструктор.
Пример 6.
//file ctime.h
#include <string.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
class CTime
{ char *timestr;
public:
CTime(); //конструктор по умолчанию
CTime(const CTime& clk); //копирующий конструктор
~CTime(); //деструктор
void show(); //функция-элемент
}; //обязательно ставить точку с запятой, т.к. class -
// объявление типа
//file ctime.cpp
#include “ctime.h”
CTime:: CTime()
{ char *str=”00:00:00”;
timestr=new char[strlen(str)+1];
strcpy(timestr,str);
}
CTime:: CTime(const CTime& clk)
{ timestr=new char[strlen(clk.timestr)+1];
strcpy(timestr,clk.timestr);
}
CTime::~ CTime()
{ delete [] timestr;
}
void CTime::show()
{ cout<<”Time is “<<timestr<<endl;
}
//file main.cpp
#include “ctime.h”
int main()
{ CTime a; //для а вызывается конструктор по умолчанию
CTime *b=new CTime; //для b вызывается конструктор по
// умолчанию
CTime e(a); //для e вызывается копирующий конструктор
//вызовем функцию-элемент
a.show(); //00:00:00
b->show(); //00:00:00
e,show(); //00:00:00
system(“PAUSE”);
}
//в конце области видимости автоматически вызываются деструкторы объектов в порядке, обратном вызову конструкторов, т.е. сначала для е, затем для d и т.д.
Форматируемый ввод/вывод. Манипуляторы
При вводе/выводе данных можно воспользоваться манипуляторами, то есть специальными функциями форматирования, которые могут находиться в теле оператора ввода/вывода. Если в манипуляторе используются параметры, то необходимо подключение заголовочного файла <iomanip.h>.
Для сохранения и восстановления состояния потока используется функция-метод класса потока flags(). Например:
long a;
a=cout.flags(); //для сохранения состояния потока в а
cout.flags(a); //для восстановления состояния потока из а
Таблица 1
Манипуляторы ввода/вывода
Манипулятор |
Назначение |
Ввод/вывод |
dec |
Вывод числовых данных в десятичной системе счисления |
Вывод |
hex |
Вывод числовых данных в шестнадцатеричной системе счисления |
Вывод |
Манипулятор |
Назначение |
Ввод/вывод |
oct |
Вывод числовых данных в восьмеричной системе счисления |
Вывод |
endl |
Вывод символа новой строки и флэширование |
Вывод |
ends |
Вывод нуля (NULL) |
Вывод |
flush |
Флэширование |
Вывод |
ws |
Пропуск начальных пробелов |
Ввод |
resetiosflags(long f) |
Сброс флагов, задаваемых в f |
Ввод/вывод |
setbase(int основание) |
Устанавливает основаниесистемы счисления для вывода данных |
Вывод |
setfill(char ch) |
Устанавливает символ заполнения ch |
Вывод |
setiosflags(long f) |
Установка флагов, задаваемых в f |
Вывод |
setprecision(int p) |
Задает число символов после десятичной точки, равным p |
Вывод |
setw(int w) |
Задает ширину поля, равной w позиций |
Вывод |
Примеры программирования
Пример 7. Вывод данных с использованием манипуляторов.
#include <iostream.h>
#include <iomanip.h>
#include <math.h>
int main()
{ double x, y;
cout << "Input x ";
cin >> x;
y = sin(x);
cout << setprecision(3);
cout << setw(7) << x;
cout << setw(7) << y;
return 0;
}
Пример 8. Описать и определить класс-список.
Файл list.h содержит описание класса.
struct list
{
int inf; // информационное поле
list *next; // указатель на следующий элемент списка
};
class CSpisok
{
list* head; // указатель на начало списка
public:
CSpisok (int n);
CSpisok (const CSpisok& s);
void print ();
~CSpisok();
};
Файл list.cpp содержит определение функций-элементов.
#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include "list.h"
CSpisok:: CSpisok(int n)
//конструктор инициализирует список из n элементов по принципу
// "очередь"
{ head = NULL;
list *p,*pn;
for (int i = 0; i<n; i++)
{
p = new list;
p−>inf = rand()%100-50;
p−>next = NULL;
if (head == NULL) head = p;
else pn−>next = p;
pn = p;
}
};
CSpisok:: CSpisok (const CSpisok& s)
//конструктор копии класса CSpisok
{ head = NULL;
list *sp = s.head, *p, *pn;
while (sp)
` { p = new list;
p−>inf = sp−>inf;
p−>next = NULL;
if (head == NULL) head = p;
else pn−>next = p;
pn = p;
sp = sp−>next;
}
};
CSpisok::~ CSpisok()
//деструктор - уничтожает объект класса список из памяти
{ list *p;
while (head)
{ p = head;
head = head−>next;
delete p;
}
};
void CSpisok::print()
//функция-элемент печати содержимого списка
{ list *p = head;
while (p)
{ cout<<setw(5)<<p−>inf;
p = p−>next;
}
cout<<endl;
};
Файл main.cpp содержит основную функцию.
#include <iostream>
#include <iomanip>
#include “list.h”
int main ()
{ CSpisok s1(10), // создание списка из 10 элементов
s2(s1), // s2- копия списка s1
s3(15); // создание списка из 15 элементов
s1.print(); // печать s1
s2.print(); // печать s2
s3.print(); // печать s3
system("PAUSE");
return 0;
}
В проект включены файлы: main.cpp и list.cpp.
Результаты выполнения программы:
-49 -50 -17 -47 -15 -29 3 -31 20 44
-49 -50 -17 -47 -15 -29 3 -31 20 44
-23 -6 -40 19 6 -46 -34 31 18 26 32 45 -29 -8 45.
Контрольные вопросы
1. Что представляет собой класс?
2. Какие спецификации доступа используются при описании класса?
3. Что является элементами класса?
4. Как осуществляется доступ к элементам класса?
5. Для чего используется указатель this?
6. Что такое конструктор?
7. Что такое деструктор?
Порядок выполнения лабораторной работы
Напишите программу согласно Вашему варианту задания.
Варианты заданий
Номер варианта |
Задание |
1, 14 |
Определить класс-строку. В класс включить два конструктора: для определения класса строки строкой символов и путем копирования другой строки (объекта класса строки). Предусмотреть функции поиска слова в строке и добавления другой строки, начиная с позиции N. |
2, 15 |
Определить класс-строку. В класс включить два конструктора: для определения класса строки строкой символов и путем копирования другой строки (объекта класса строки). Предусмотреть функции слияния двух строк и функцию подсчёта предложений в строке. |
3, 16 |
Определить класс-строку. В класс включить два конструктора: для определения класса строки строкой символов и путем копирования другой строки (объекта класса строки). Предусмотреть функции сортировки слов в строке по-алфавиту и подсчёта количества слов. |
4, 17 |
Определить класс список элементов. В определение класса включить два конструктора: для определения списка по его размеру и путем копирования другого списка. Предусмотреть функции подсчёта количества элементов списка и добавления одного списка в другой список, начиная с позиции N. |
5, 18 |
Определить класс список элементов. В определение класса включить два конструктора для определения списка по его размеру и путем копирования другого списка. Предусмотреть функции сортировки списка по возрастанию и вывода на экран в обратном порядке. |
6, 19 |
Определить класс список элементов. В определение класса включить два конструктора для определения списка по его размеру и путем копирования другого списка. Предусмотреть функции инверсии списка (123->321) и поиска подсписка в списке. |
7, 20 |
Определить класс сортированный список элементов. В определение класса включить два конструктора для определения списка по его размеру и путем копирования другого списка. Предусмотреть функции добавления элемента и слияния двух сортированных списков. |
8, 21 |
Определить класс список элементов. В определение класса включить два конструктора для определения списка по его размеру и путем копирования другого списка. Предусмотреть функции формирования нового списка из элементов, входящих только в один из двух других списков и вычисления суммы элементов списков. |
9, 22 |
Определить класс матрицу. В класс включить два конструктора для определения матрицы по количеству элементов и путем копирования другой матрицы. Предусмотреть функции вычисления детерминанта матрицы и умножения матрицы на число. |
10, 23 |
Определить класс стек. В класс включить два конструктора для определения стека по его размеру и путем копирования другого стека. Предусмотреть функции вычисления среднего арифметического из элементов стека и нахождения элемента по его номеру. |
11, 24 |
Определить класс вектор. В класс включить два конструктора для определения вектора по его размеру и путем копирования другого вектора. При задании вектора по его размеру предусмотреть его заполнение случайными числами. Предусмотреть функции умножения векторов и подсчёта суммы элементов вектора. |
12, 25 |
Определить класс вектор. В класс включить два конструктора для определения вектора по его размеру и путем копирования другого вектора. При задании вектора по его размеру предусмотреть его заполнение случайными числами. Предусмотреть функции нахождения максимального и минимального из элементов вектора и умножения вектора на число. |
13, 26 |
Определить класс вектор. В класс включить два конструктора для определения вектора по его размеру и путем копирования другого вектора. При задании вектора по его размеру предусмотреть его заполнение случайными числами. Предусмотреть функции сортировки вектора по возрастанию и нахождения среднего арифметического из элементов вектора. |
С уважением ИЦ "KURSOVIKS"!