
s12-lab-book
.pdf
ООП - лабораторные работы (весна 2012), Release 0
59{
60ostr << "]";
61for (Stack stCopy(st); 0 == stCopy.empty(); )
62{
63
64
65
66
67
68
ostr << stCopy.top(); stCopy.pop();
if (0 == stCopy.empty())
{
ostr << " ";
}
69}
70ostr << "]";
71}
72
73int main()
74{
75using namespace std;
76Stack stDef;
77cout << "create stDef, stDef.empty() -> " << stDef.empty();
78cout << "\n stDef -> ";
79print(cout, stDef);
80
81Stack stFirst;
82stFirst.pop();
83stFirst.push(1);
84cout << "\npush into stFirst, stFirst.empty() -> " << stDef.empty();
85stFirst.push(2);
86stFirst.push(3);
87cout << "\n stFirst -> ";
88print(cout, stFirst);
89
90
91
92
93
94
95
96
97
98
cout << "\n\nLet's copy stFirst to stSec"; Stack stSec(stFirst);
cout << "\n stFirst -> "; print(cout, stFirst);
cout << "\n stSec -> "; print(cout, stSec);
cout << "\n copy stFirst to stSec,\n stSec -> "; print(cout, stSec);
99
100
101
102
103
cout << "\n\nLet's stSec"; stSec = stSec;
cout << "\n stSec -> "; print(cout, stSec);
104 |
// FIXME - other test |
105 |
|
106return 0;
107}
3.1. Пример - класс стека на динамическом массиве std::vector<> |
18 |

ООП - лабораторные работы (весна 2012), Release 0
Результаты работы программы (lab-03-00.exe)
3.1. Пример - класс стека на динамическом массиве std::vector<> |
19 |

ООП - лабораторные работы (весна 2012), Release 0
3.2 Пример - класс стека на односвязном списке
Задача - написать реализацию стека на односвязном списке
1#include <iostream>
2#include <cassert>
3
4using namespace std;
5
6class Stack
7{
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
35 };
36
typedef int value_type; public:
Stack() : m_pHead(0) {} Stack(const Stack& obj); ~Stack();
Stack& operator=(const Stack& rhs); void push(const value_type& val); void pop();
bool empty() const { return (0 == m_pHead); } int& top() { return m_pHead->m_val; }
const int& top() const { return m_pHead->m_val; } private:
struct ListNode; struct ListNode
{
ListNode* m_pNext; //< голова списка value_type m_val; //< элемент стека ListNode(ListNode* pNext, const value_type& val)
: m_pNext(pNext) , m_val(val)
{
}
};
ListNode* m_pHead; private:
void cloneFrom(ListNode* pHead); void destroy();
37Stack::Stack(const Stack& obj) : m_pHead(0)
38{
39cloneFrom(obj.m_pHead);
40}
41
42void
43Stack::cloneFrom(ListNode* pHead)
44{
45assert(0 == m_pHead);
46
47
48
49
50
51
52
53
54
55
56
57
58
ListNode* pPrev(0);
for (ListNode* pCopyFrom(pHead); 0 != pCopyFrom; pCopyFrom = pCopyFrom->m_pNext )
{
ListNode* pCopy(new ListNode(0, pCopyFrom->m_val)); if (0 != pPrev)
{
pPrev->m_pNext = pCopy;
}
else
{
m_pHead = pCopy;
3.2. Пример - класс стека на односвязном списке |
20 |

ООП - лабораторные работы (весна 2012), Release 0
59
60
}
pPrev = pCopy;
61}
62}
63
64Stack::~Stack()
65{
66destroy();
67}
68
69void Stack::destroy()
70{
71for (ListNode* pCur(m_pHead); 0 != pCur; )
72{
73
74
75
ListNode* pNext(pCur->m_pNext); delete pCur;
pCur = pNext;
76}
77m_pHead = 0;
78}
79
80Stack&
81Stack::operator=(const Stack& rhs)
82{
83if (&rhs != this)
84{
85
86
destroy(); cloneFrom(rhs.m_pHead);
87}
88return *this;
89}
90
91void
92Stack::push(const Stack::value_type& val)
93{
94ListNode* pNewHead(new ListNode(m_pHead, val));
95m_pHead = pNewHead;
96}
97
98void
99Stack::pop()
100{
101if (0 != m_pHead)
102{
103
104
105
ListNode* pDeletedNode(m_pHead); m_pHead = m_pHead->m_pNext; delete pDeletedNode;
106}
107}
108
109void print(ostream& ostr, const Stack& st)
110{
111ostr << "]";
112for (Stack stCopy(st); 0 == stCopy.empty(); )
113{
114
115
116
117
118
119
ostr << stCopy.top(); stCopy.pop();
if (0 == stCopy.empty())
{
ostr << " ";
}
120}
121ostr << "]";
3.2. Пример - класс стека на односвязном списке |
21 |

ООП - лабораторные работы (весна 2012), Release 0
122 }
123
124int main()
125{
126using namespace std;
127Stack stDef;
128cout << "create stDef, stDef.empty() -> " << stDef.empty();
129cout << "\n stDef -> ";
130print(cout, stDef);
131
132Stack stFirst;
133stFirst.pop();
134stFirst.push(1);
135cout << "\npush into stFirst, stFirst.empty() -> " << stDef.empty();
136stFirst.push(2);
137stFirst.push(3);
138cout << "\n stFirst -> ";
139print(cout, stFirst);
140
141
142
143
144
145
146
147
148
149
cout << "\n\nLet's copy stFirst to stSec"; Stack stSec(stFirst);
cout << "\n stFirst -> "; print(cout, stFirst);
cout << "\n stSec -> "; print(cout, stSec);
cout << "\n copy stFirst to stSec,\n stSec -> "; print(cout, stSec);
150
151
152
153
154
cout << "\n\nLet's stSec"; stSec = stSec;
cout << "\n stSec -> "; print(cout, stSec);
155 |
// FIXME - other test |
156 |
|
157return 0;
158}
Результаты работы программы (lab-03-01.cpp)
3.2. Пример - класс стека на односвязном списке |
22 |

ООП - лабораторные работы (весна 2012), Release 0
3.3Пример - разнесение кода стека на односвязном списке (заголовок и реализация)
Задача - разнести объявление класса и определение его методов в соответствующие заголовочный файл и файл реализации.
Заголовочный файл для класса (liststack.h).
1#ifndef LISTSTACK_H_20120220
2#de ne LISTSTACK_H_20120220
3
4class ListStack
5{
6
7
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
typedef int value_type; public:
ListStack() : m_pHead(0) {} ListStack(const ListStack& obj); ~ListStack();
ListStack& operator=(const ListStack& rhs); void push(const value_type& val);
void pop();
bool empty() const { return (0 == m_pHead); } int& top() { return m_pHead->m_val; }
const int& top() const { return m_pHead->m_val; } private:
struct ListNode; struct ListNode
{
ListNode* m_pNext; //< голова списка value_type m_val; //< элемент стека ListNode(ListNode* pNext, const value_type& val)
: m_pNext(pNext) , m_val(val)
{
}
};
ListNode* m_pHead; private:
void cloneFrom(ListNode* pHead); void destroy();
35 #endif //LISTSTACK_H_20120220
Файл реализации для класса (liststack.cpp).
1#include "liststack.h"
2
3#include <iostream>
4#include <cassert>
5
6ListStack::ListStack(const ListStack& obj)
7: m_pHead(0)
8{
9cloneFrom(obj.m_pHead);
10 }
11
12void
13ListStack::cloneFrom(ListNode* pHead)
14{
15assert(0 == m_pHead);
16
3.3. Пример - разнесение кода стека на односвязном списке (заголовок и реализация) |
23 |

ООП - лабораторные работы (весна 2012), Release 0
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 }
33
ListNode* pPrev(0);
for (ListNode* pCopyFrom(pHead); 0 != pCopyFrom; pCopyFrom = pCopyFrom->m_pNext )
{
ListNode* pCopy(new ListNode(0, pCopyFrom->m_val)); if (0 != pPrev)
{
pPrev->m_pNext = pCopy;
}
else
{
m_pHead = pCopy;
}
pPrev = pCopy;
}
34ListStack::~ListStack()
35{
36destroy();
37}
38
39void ListStack::destroy()
40{
41
42
43
44
45
46
47
48 }
49
for (ListNode* pCur(m_pHead); 0 != pCur; )
{
ListNode* pNext(pCur->m_pNext); delete pCur;
pCur = pNext;
}
m_pHead = 0;
50ListStack&
51ListStack::operator=(const ListStack& rhs)
52{
53
54
55
56
57
58
59 }
60
if (&rhs != this)
{
destroy(); cloneFrom(rhs.m_pHead);
}
return *this;
61void
62ListStack::push(const ListStack::value_type& val)
63{
64
65
ListNode* pNewHead(new ListNode(m_pHead, val)); m_pHead = pNewHead;
66 }
67
68void
69ListStack::pop()
70{
71
72
73
74
75
76
77 }
if (0 != m_pHead)
{
ListNode* pDeletedNode(m_pHead); m_pHead = m_pHead->m_pNext; delete pDeletedNode;
}
Основная программа с тестирующим кодом (lab-03-02.cpp).
3.3. Пример - разнесение кода стека на односвязном списке (заголовок и реализация) |
24 |

ООП - лабораторные работы (весна 2012), Release 0
1#include "liststack.h"
2
3#include <iostream>
4
5using namespace std;
6
7void print(ostream& ostr, const ListStack& st)
8{
9
10
11
12
13
14
15
16
17
18
19
20 }
21
ostr << "]";
for (ListStack stCopy(st); 0 == stCopy.empty(); )
{
ostr << stCopy.top(); stCopy.pop();
if (0 == stCopy.empty())
{
ostr << " ";
}
}
ostr << "]";
22int main()
23{
24
25
26
27
28
29
using namespace std; ListStack stDef;
cout << "create stDef, stDef.empty() -> " << stDef.empty(); cout << "\n stDef -> ";
print(cout, stDef);
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
ListStack stFirst; stFirst.pop(); stFirst.push(1);
cout << "\npush into stFirst, stFirst.empty() -> " << stDef.empty(); stFirst.push(2);
stFirst.push(3);
cout << "\n stFirst -> "; print(cout, stFirst);
cout << "\n\nLet's copy stFirst to stSec"; ListStack stSec(stFirst);
cout << "\n stFirst -> "; print(cout, stFirst);
cout << "\n stSec -> "; print(cout, stSec);
cout << "\n copy stFirst to stSec,\n stSec -> "; print(cout, stSec);
48
49
50
51
52
cout << "\n\nLet's stSec";
stSec = stSec; |
|
cout << "\n stSec |
-> "; |
print(cout, stSec); |
// FIXME - other test |
53return 0;
54}
Результаты работы программы (lab-03-02.cpp)
3.3. Пример - разнесение кода стека на односвязном списке (заголовок и реализация) |
25 |

ООП - лабораторные работы (весна 2012), Release 0
3.4Пример - создание шаблонного класса для стека на односвязном списке
Задача - написать шаблонную реализацию стека на односвязном списке Заголовочный файл шаблонного класса (tplstack.h).
1#include <iostream>
2#include <cassert>
3
4template<typename T>
5class TplStack
6{
7
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 };
35
typedef T value_type; public:
TplStack();
TplStack(const TplStack& obj); ~TplStack();
TplStack& operator=(const TplStack& rhs); void push(const T& val);
void pop();
bool empty() const; int& top();
const int& top() const; private:
struct ListNode; struct ListNode
{
ListNode* m_pNext; //< голова списка value_type m_val; //< элемент стека ListNode(ListNode* pNext, const value_type& val)
: m_pNext(pNext) , m_val(val)
{
}
};
ListNode* m_pHead; private:
void cloneFrom(ListNode* pHead); void destroy();
36template<typename T>
37TplStack<T>::TplStack()
38: m_pHead(0)
39{
40}
41
42template<typename T>
43TplStack<T>::TplStack(const TplStack<T>& obj)
44: m_pHead(0)
45{
46cloneFrom(obj.m_pHead);
47}
48
49template<typename T>
50void
51TplStack<T>::cloneFrom(ListNode* pHead)
52{
53assert(0 == m_pHead);
54
55 |
ListNode* pPrev(0); |
3.4. Пример - создание шаблонного класса для стека на односвязном списке |
26 |

ООП - лабораторные работы (весна 2012), Release 0
56for (ListNode* pCopyFrom(pHead); 0 != pCopyFrom;
57pCopyFrom = pCopyFrom->m_pNext )
58{
59
60
61
62
63
64
65
66
67
68
ListNode* pCopy(new ListNode(0, pCopyFrom->m_val)); if (0 != pPrev)
{
pPrev->m_pNext = pCopy;
}
else
{
m_pHead = pCopy;
}
pPrev = pCopy;
69}
70}
71
72template<typename T>
73TplStack<T>::~TplStack()
74{
75destroy();
76}
77
78template<typename T>
79void TplStack<T>::destroy()
80{
81for (ListNode* pCur(m_pHead); 0 != pCur; )
82{
83
84
85
ListNode* pNext(pCur->m_pNext); delete pCur;
pCur = pNext;
86}
87m_pHead = 0;
88}
89
90template<typename T>
91TplStack<T>&
92TplStack<T>::operator=(const TplStack<T>& rhs)
93{
94if (&rhs != this)
95{
96
97
destroy(); cloneFrom(rhs.m_pHead);
98}
99return *this;
100}
101
102template<typename T>
103void
104TplStack<T>::push(const T& val)
105{
106ListNode* pNewHead(new ListNode(m_pHead, val));
107m_pHead = pNewHead;
108}
109
110template<typename T>
111void
112TplStack<T>::pop()
113{
114if (0 != m_pHead)
115{
116
117
118
ListNode* pDeletedNode(m_pHead); m_pHead = m_pHead->m_pNext; delete pDeletedNode;
3.4. Пример - создание шаблонного класса для стека на односвязном списке |
27 |