-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCodeSnap-ClassAnatomy.cpp.html
More file actions
318 lines (266 loc) · 10.6 KB
/
CodeSnap-ClassAnatomy.cpp.html
File metadata and controls
318 lines (266 loc) · 10.6 KB
1
2
3
4
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
<!----------------------------------------------------------------------------
CodeSnap-ClassAnatomy.cs.htm
Published 19 Mar 2017
Jim Fawcett, CSE687 : Object Oriented Design, Summer 2017
Note:
- Markup characters in the text part, enclosed in <pre>...</pre> have to be
replaced with escape sequences, e.g., < becomes < and > becomes >
- Be careful that you don't replace genuine markup characters with escape
sequences, e.g., everything outside of the <pre>...</pre> section.
----------------------------------------------------------------------------->
<html>
<head>
<script src="js/ScriptsUtilities.js"></script>
<script src="js/ScriptsTemplate.js"></script>
<script src="js/ScriptsKeyboard.js"></script>
<script src="js/ScriptsMenuCpp.js"></script>
<link rel="stylesheet" href="css/StylesTemplate.css" />
<link rel="stylesheet" href="css/StylesMenu.css" />
<style>
h3 {
font-weight: normal;
}
</style>
</head>
<body id="github" onload="initializeMenu()">
<nav>
<div id="navbar"></div>
</nav>
<a id="Next" href="CodeSnap-ClassAnatomy.txt.html">N</a>
<a id="Prev" href="CodeSnap-ClassAnatomy.h.html">P</a>
<navKeys-Container>
<nav-Key id="sKey" onclick="toggleSwipeEvents()">S</nav-Key>
<nav-Key id="rKey" onclick="location.reload()">R</nav-Key>
<nav-Key id="tKey" onclick="scrollPageTop()">T</nav-Key>
<nav-Key id="bKey" onclick="scrollPageBottom()">B</nav-Key>
<nav-Key id="hKey" onclick="helpWin()">H</nav-Key>
<nav-Key id="pKey" onclick="loadPrev()">P</nav-Key>
<nav-Key id="nKey" onclick="loadNext()">N</nav-Key>
</navKeys-Container>
<h3>
<a href="CodeSnap-ClassAnatomy.h.html">ClassAnatomy.h</a>,
<a href="CodeSnap-ClassAnatomy.cpp.html">ClassAnatomy.cpp</a>,
<a href="CodeSnap-ClassAnatomy.txt.html">ClassAnatomy.txt</a>,
<!--<a class="disable" href="#">Code folder</a>,-->
<a href="DesignNote-CppClasses.html">Classes webpage</a>
</h3>
<div class="indent">
Illustrates all of the basic parts of a class, e.g., Constructors, operators, destructor, and member data.
</div>
<hr />
<h3>ClassAnatomy.cpp</h3>
<div class='code'>
<pre class="codesnap">
/////////////////////////////////////////////////////////////////////////////
// TestClass.cpp - Implemented to demonstrate class operations //
// //
// Application: CSE687 - OOD demonstration, Fall 2018 //
// Platform: Dell XPS 8920, Win 10 Pro, Visual Studio 2017 //
// Author: Jim Fawcett, Syracuse University, CST 4-187 //
// jfawcett@twcny.rr.com, http://ecs.syr.edu/faculty/fawcett //
/////////////////////////////////////////////////////////////////////////////
#include "TestClass.h"
#include "..\Helpers\Helpers.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <memory>
// add this to stringUtiltities
//----< remove a substring if it exists, returning by value >----------------
std::string remove(std::string& src, const std::string& removed)
{
std::string modified = src;
size_t pos = modified.find(removed);
if (pos >= modified.size())
return modified;
std::string ret = modified.erase(pos, removed.size());
return ret;
}
//----< remove a substring if it exists, returning by reference >------------
void inPlaceRemove(std::string& src, const std::string& removed)
{
size_t pos = src.find(removed);
if (pos >= src.size())
return;
src = src.erase(pos, removed.size());
}
//----< configure output lines into fixed size fields >----------------------
void showLine(const std::string& msg, size_t line, const std::string& function)
{
std::ostringstream lineStr, funcStr;
lineStr << line;
funcStr << function;
std::string fStr = funcStr.str();
inPlaceRemove(fStr, "__thiscall "); // remove VSC++ compiler decorations
inPlaceRemove(fStr, "__cdecl "); // as not relevant for this discussion
std::cout << "\n " << std::setw(40) << std::left << msg.substr(0, 40);
std::cout << std::setw(9) << " at line " << std::setw(5) << std::right << "#" + lineStr.str() + " ";
std::cout << std::left << fStr.substr(0, 60);
}
//----< default constructor >----------------------------------------------
Test::Test()
{
showLine("void construction of Test",__LINE__, __FUNCSIG__);
name_ = "unnamed";
}
//----< promotion constructor >--------------------------------------------
Test::Test(const std::string& name) : name_(name)
{
std::string msg = "named construction of " + name;
showLine(msg, __LINE__, __FUNCSIG__);
}
//----< copy constructor >-------------------------------------------------
Test::Test(const Test& t) : name_(t.name_)
{
std::string msg = "copy of " + name_;
showLine(msg, __LINE__, __FUNCSIG__);
}
//----< move constructor >-------------------------------------------------
Test::Test(Test&& t) : name_(std::move(t.name_))
{
std::string msg = "move of " + name_;
showLine(msg, __LINE__, __FUNCSIG__);
}
//----< copy assignment operator >-----------------------------------------
Test& Test::operator=(const Test& t)
{
if (this == &t)
return *this;
name_ = t.name_;
std::string msg = "copy assignment of " + name_;
showLine(msg, __LINE__, __FUNCSIG__);
return *this;
}
//----< move assignment operator >-----------------------------------------
Test& Test::operator=(Test&& t)
{
if (this == &t)
return *this;
name_ = std::move(t.name_);
std::string msg = "move assignment of " + name_;
showLine(msg, __LINE__, __FUNCSIG__);
return *this;
}
//----< destructor >-------------------------------------------------------
Test::~Test()
{
std::string msg = "destruction of " + name_;
showLine(msg, __LINE__, __FUNCSIG__);
}
//----< name "property" >--------------------------------------------------
std::string& Test::name()
{
return name_;
}
//----< enunciator >-------------------------------------------------------
void Test::say()
{
std::cout << "\n my name is " << name_;
}
//----< cosmetic object that emits line feeds on termination >-------------
struct lineFeeds
{
~lineFeeds()
{
std::cout << "\n\n";
}
} cosmetic;
//----< demonstration of move construction >-------------------------------
Test demoFunc()
{
Test demo("function demo's temporary Test");
showLine(demo.name(), __LINE__, __FUNCSIG__);
return demo;
}
//----< test stub >--------------------------------------------------------
#include <stdexcept>
int main()
{
using Helper = UtilityHelpers::Utilities;
Helper::title("Demonstrate Test Class");
showLine("-- promotion construction of Test Fred", __LINE__, __FUNCSIG__);
Test t("Fred"); // named construction
showLine("-- copy construction of Test Fred", __LINE__, __FUNCSIG__);
Test t1 = t; // copy construction
showLine("-- call demoFunc()", __LINE__, __FUNCSIG__);
Test t2 = demoFunc(); // move construction
showLine("-- void construction of unnamed Test", __LINE__, __FUNCSIG__);
Test t3;
showLine("-- assignment of Test Fred", __LINE__, __FUNCSIG__);
t3 = t1; // copy assignment
showLine("-- assignment of temporary test", __LINE__, __FUNCSIG__);
t3 = Test(); // move assignment from temporary
std::cout << "\n";
t1.name() = "t1";
t2.name() = "t2";
t3.name() = "t3";
Helper::title("Creating initialized std::vector of Tests");
showLine("-- initialize vector with copies of t1 & t2, and move of t3", __LINE__, __FUNCSIG__);
std::vector<Test> vt{ t1, t2, std::move(t3) };
for (auto& e : vt)
{
e.say();
}
std::cout << "\n";
Helper::title("Testing push_backs");
showLine("-- promotion construction of t4", __LINE__, __FUNCSIG__);
Test t4("t4");
showLine("-- promotion construction of t5", __LINE__, __FUNCSIG__);
Test t5("t5");
showLine("-- push_back of t4", __LINE__, __FUNCSIG__);
vt.push_back(t4);
showLine("-- push_back of std::move(t5)", __LINE__, __FUNCSIG__);
vt.push_back(std::move(t5));
for (auto& e : vt)
{
e.say();
}
std::cout << "\n";
Helper::title("Creating vector of smart pointers");
/*
* - unique_ptr<T> is a smart pointer to an instance t of type T
* - it assumes it is the only reference to t and that t is stored on the native heap
* - since it represents unique ownership, it cannot be copied or assigned, only moved
* - when it goes out of scope, either through a normal exit from the scope where it was defined
* or because an exception was thrown, it calls delete on its iternal pointer to t
*/
showLine("-- attach unique_ptr sp1 to new Test t6", __LINE__, __FUNCSIG__);
std::unique_ptr<Test> sp1(new Test("t6"));
showLine("-- attach unique_ptr sp2 to new Test t7", __LINE__, __FUNCSIG__);
std::unique_ptr<Test> sp2(new Test("t7"));
showLine("-- create vector of these unique_ptrs", __LINE__, __FUNCSIG__);
std::vector<std::unique_ptr<Test>> vp;
showLine("-- push_back std::move(sp1)", __LINE__, __FUNCSIG__);
vp.push_back(std::move(sp1));
showLine("-- push_back std::move(sp2)", __LINE__, __FUNCSIG__);
vp.push_back(std::move(sp2));
///////////////////////////////////////////////////////////////////////////
// The line below doesn't work. Initializer_lists are constant so
// you can copy but can't move out of them. Unique_ptr is moveable but
// not copyable so you have to use push_back
//
// std::vector<std::unique_ptr<Test>> vp { std::move(sp1), std::move(sp2) };
///////////////////////////////////////////////////////////////////////////
// Resetting sp2 does not reset the vector vp's unique_ptr.
// Instead, it is resetting the now invalid sp2 in main to a new valid Test instance, t8.
showLine("-- reset sp2 to new Test(t8)", __LINE__, __FUNCSIG__);
sp2.reset(new Test("t8")); // re-initializes sp2 to point to t8, original object was moved into vector so nothing to delete
showLine("-- reset sp2 to new Test(t9)", __LINE__, __FUNCSIG__);
sp2.reset(new Test("t9")); // re-initializes sp2 to point to t9 then deletes t8
for (auto& p : vp)
{
p->say();
}
std::cout << "\n";
Helper::title("Done with testing");
}
</pre>
</div>
<!--<div class="photo">
<img src="pictures/CSTstrip.jpg" width="100%" />
</div>-->
<info-bar></info-bar>
</body>
</html>