s12-lab-book
.pdf
ООП - лабораторные работы (весна 2012), Release 0
1.4 Задания (лабораторная работа 1)
1.4.1 Копирование примеров
Для каждого примера:
•набрать (именно набрать, а не скопировать-вставить) текст программы и произвести отладку (программа должна собираться без ошибок и запускаться)
•убедится, что результат работы программы совпадает с указанным
1.4.2Изучение и модификация программы печать таблицы функции
Выяснить, для чего именно в программу включен каждый из заголовочных файлов.
Todo
сформулирвать разумные варианты
Модифицировать программу печати функции так, чтобы выводить
•1=x в диапазоне [ 1; 1] с шагом 0.1
•1=x2 в диапазоне [ 1; 1] с шагом 0.1
•1=sin(x) в диапазоне [ pi=2; pi=2] с шагом pi/24
•1=sin2(x) в диапазоне [ pi=2; pi=2] с шагом pi/24
•1=sin(x2) в диапазоне [ pi=2; pi=2] с шагом pi/24
•1=cos(x) в диапазоне [ pi=2; pi=2] с шагом pi/24
•1=cos2(x) в диапазоне [ pi=2; pi=2] с шагом pi/24
•1=cos(x2) в диапазоне [ pi=2; pi=2] с шагом pi/24
1.4. Задания (лабораторная работа 1) |
8 |
CHAPTER
TWO
ЛАБОРАТОРНАЯ РАБОТА (СОЗДАНИЕ СОБСТВЕННЫХ КЛАССОВ)
Теория
•абстрактный тип данных Число (АТД Число)
•умолчательный конструктор и его тестирование
•деструктор
•конструктор копирования
•список инициализации
•оператор присваивания
•управление доступом (public и private)
•перегрузка операторов (на примере сложения)
•константные методы
9
ООП - лабораторные работы (весна 2012), Release 0
2.1 Пример - класс рациональных чисел
Задача - написать класс рационалных чисел.
Результаты работы программы (lab-02-00.exe)
2.1. Пример - класс рациональных чисел |
10 |
ООП - лабораторные работы (весна 2012), Release 0
1#include <iostream>
2#include <cassert>
3#include <sstream>
4
5using namespace std;
6
7class RatNum
8{
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 };
34
public: /**
\brief создание рациональногог числа (num / denum) \param num [in] - числитель
\param denum [in] - знаменатель, != 0 нулевое значение -> assert
*/
RatNum(const int num = 0, int denum = 1); RatNum(const RatNum& obj);
~RatNum();
RatNum& operator=(const RatNum& rhs); /**
\brief форматированные вывод значения числа в поток \param ostr [in/out] - поток для вывода
\retval ostream - поток */
ostream& writeToTxt(ostream& ostr) const; istream& readFromTxt(istream& istr); RatNum& operator+=(const RatNum& rhs);
private:
int m_num; //< числитель int m_denum; //< знаменатель
private:
void normalize();
35/**
36\brief форматированные вывод в поток
37\param ostr [in] - поток для вывода
38\param rhs [in] - рациональное число
39*/
40ostream& operator<<(ostream& ostr, const RatNum& rhs);
41
42 |
istream& operator>>(istream& ostr, RatNum& rhs); |
43 |
|
44 |
RatNum operator+(const RatNum& lhs, const RatNum& rhs); |
45
46int main()
47{
48
49
50
51
52
53
54
55
56
57
58
59
RatNum n0;
cout << n0 << endl; RatNum copy(n0); cout << copy << endl; RatNum n1(1, 2);
cout << n1 << endl; RatNum n2(2, -3); cout << n2 << endl; RatNum n3(-2, 3); n3.writeToTxt(cout); cout << endl;
60
61
62
63
cout << "Before n = n -> n = " << n1; n1 = n1;
cout << "\nAfter n = n -> n = "; cout << n1 << endl;
2.1. Пример - класс рациональных чисел |
11 |
ООП - лабораторные работы (весна 2012), Release 0
64
65cout << "Before n0 = n1 = n2 -> n0 = " << n0;
66cout << " n1 = " << n1;
67cout << " n2 = " << n2;
68n0 = n1 = n2;
69cout << "\nAfter n0 = n1 = n2 -> n0 = " << n0;
70cout << " n1 = " << n1;
71cout << " n2 = " << n2;
72
73RatNum additionForEqPlus(1);
74cout << "\n\nCheck operator +=\n";
75cout << "n0 = " << n0;
76n0 += additionForEqPlus;
77cout << ", after += " << additionForEqPlus << " -> n0 = " << n0;
78
79
80
81
82
83
84
RatNum additionForPlus(2, 5);
cout << "\n\nCheck operator +\n"; cout << "n0 = " << n0;
n0 += additionForPlus;
cout << ", after + " << additionForPlus << " -> n0 = " << n0;
85cout << "\n\nLet's read from stream good value";
86stringstream strmWithGoodRatNum("5/9\n");
87RatNum vv;
88strmWithGoodRatNum >> vv;
89cout << "\nread from stream value is " << vv;
90cout << "\nstream good() gives " << strmWithGoodRatNum.good();
91
92cout << "\n\nLet's read from stream bad value";
93vv = RatNum();
94stringstream strmWithBadRatNumBySep("5-9\n");
95strmWithBadRatNumBySep >> vv;
96cout << "\nread from stream value is " << vv;
97cout << "\nstream good() gives " << strmWithBadRatNumBySep.good();
98
99cout << "\n\nLet's read from stream bad value";
100stringstream strmWithBadRatNumByDenum("5/0\n");
101vv = RatNum();
102strmWithBadRatNumByDenum >> vv;
103cout << "\nread from stream value is " << vv;
104cout << "\nstream good() gives " << strmWithBadRatNumByDenum.good();
105
106return 0;
107}
108
109RatNum::RatNum(const int num, int denum)
110: m_num(num)
111, m_denum(denum)
112{
113assert(m_denum != 0);
114normalize();
115}
116
117RatNum::RatNum(const RatNum& obj)
118: m_num(obj.m_num)
119, m_denum(obj.m_denum)
120{
121}
122
123RatNum::~RatNum()
124{
125}
126
2.1. Пример - класс рациональных чисел |
12 |
ООП - лабораторные работы (весна 2012), Release 0
127RatNum&
128RatNum::operator=(const RatNum& rhs)
129{
130if (&rhs != this)
131// нет присвоения самому себе
132{
133
134
m_num = rhs.m_num; m_denum = rhs.m_denum;
135}
136return *this;
137}
138
139ostream&
140RatNum::writeToTxt(ostream& ostr) const
141{
142ostr << m_num << '/' << m_denum;
143return ostr;
144}
145
146istream&
147RatNum::readFromTxt(istream& istr)
148{
149int num(0);
150int denum(0);
151istr >> num;
152if (istr.good())
153{
154
155
156
157
158
159
160
161
162
163
164
165
166
167
char sep(0); istr >> sep; if ('/' != sep)
{
istr.setstate(ios_base::failbit);
}
else
{
istr >> denum; if (0 == denum)
{
istr.setstate(ios_base::failbit);
}
}
168}
169if (istr.good())
170{
171
172
173
m_num = num; m_denum = denum; normalize();
174}
175return istr;
176}
177
178RatNum&
179RatNum::operator+=(const RatNum& rhs)
180{
181m_num = m_num * rhs.m_denum + rhs.m_num * m_denum;
182m_denum *= rhs.m_denum;
183normalize();
184return *this;
185}
186
187void
188RatNum::normalize()
189{
2.1. Пример - класс рациональных чисел |
13 |
ООП - лабораторные работы (весна 2012), Release 0
190if (m_denum < 0)
191{
192
193
m_num *= -1; m_denum *= -1;
194}
195}
196
197ostream&
198operator<<(ostream& ostr, const RatNum& rhs)
199{
200return rhs.writeToTxt(ostr);
201}
202
203istream&
204operator>>(istream& istr, RatNum& rhs)
205{
206return rhs.readFromTxt(istr);
207}
208
209RatNum
210operator+(const RatNum& lhs, const RatNum& rhs)
211{
212RatNum summValue(lhs);
213summValue += rhs;
214return summValue;
215}
2.1. Пример - класс рациональных чисел |
14 |
ООП - лабораторные работы (весна 2012), Release 0
2.2 Задания (лабораторная работа 2)
2.2.1 Копирование примера
Для примера:
•набрать текст программы и произвести отладку (программа должна собираться без ошибок и запускаться)
•убедится, что результат работы программы совпадает с указанным
2.2.2Доработка примера
Произвести модификацию кода примера:
•дописать комментарии
•реализовать полную функциональность АТД Число (доделать остальные операторы)
•написать нормализацию рационального числа (например, с помощью алгоритма Евклида для поиска НОД)
•обеспечить тесты для всех методов класса рациональных чисел
2.2. Задания (лабораторная работа 2) |
15 |
CHAPTER
THREE
ЛАБОРАТОРНАЯ РАБОТА (СОЗДАНИЕ КЛАССОВ И УПРАВЛЕНИЕ ПАМЯТЬЮ)
Теория
•абстрактный тип данных Стек (АТД Стек)
•абстрактный тип данных Массив (АТД Массив)
•использование шаблонных классов
•основные возможности std::vector<>
•структура данных односвязный список
•пользовательский тип данных структура (struct)
•вложенные типы (на примере структуры внутри класса)
•предварительное объявление типа
•разделение кода на заголовочный файл и файл реализации
•управление памятью и использование операторов new и delete
•метапрограммирование
•синтаксис шаблонного кода
•особенности размещения определения шаблонных функций (в заголовочных файлах)
•техника написания шаблонного кода (от конкретного класса к обощенному)
•встроенные массивы
•динамические массивы и использование операторов new[] и delete[]
16
ООП - лабораторные работы (весна 2012), Release 0
3.1 Пример - класс стека на динамическом массиве std::vector<>
Задача - написать реализацию стека с использованием std::vector<>
1#include <iostream>
2#include <vector>
3#include <cassert>
4
5using namespace std;
6
7class Stack
8{
9
10
11
12
13
14
15
16
17
18
19
20
21
22 };
23
public:
Stack() : m_data() {}
Stack(const int reserved) : m_data(reserved) {} Stack(const Stack& obj) : m_data(obj.m_data) {} ~Stack() {}
Stack& operator=(const Stack& rhs);
void push(const int& val) { m_data.push_back(val); } void pop();
bool empty() const { return m_data.empty(); } int& top();
const int& top() const; private:
std::vector<int> m_data;
24Stack&
25Stack::operator=(const Stack& rhs)
26{
27
28
29
30
31
32 }
33
if (&rhs != this)
{
m_data = rhs.m_data;
}
return *this;
34void
35Stack::pop()
36{
37
38
39
40
41 }
42
if (0 == m_data.empty())
{
m_data.pop_back();
}
43int&
44Stack::top()
45{
46
47
assert(0 == m_data.empty()); return m_data.back();
48 }
49
50const int&
51Stack::top() const
52{
53
54
assert(0 == m_data.empty()); return m_data.back();
55 |
} |
|
|
56 |
|
57 |
|
58 |
void print(ostream& ostr, const Stack& st) |
3.1. Пример - класс стека на динамическом массиве std::vector<> |
17 |
