Skip to content

Commit 47d96fa

Browse files
committed
Lecture 13 - Copy Constructor, Destructor, Assignment Operator
1 parent da78e00 commit 47d96fa

3 files changed

Lines changed: 336 additions & 0 deletions

File tree

Lecture 13.md

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
# Lecture 13 - Oct. 27, 2015
2+
3+
"The Big Three", Copy Constructor, Destructor, operator=
4+
5+
## Copy Constructor
6+
7+
Used to construct a new object as a copy of an existing object.
8+
9+
```cpp
10+
Student billy(60, 70, 80);
11+
Student bobby = billy;
12+
```
13+
14+
There is a built-in copy constructor.
15+
16+
Every class "comes with":
17+
18+
* Default constructor **(goes away when you write your own constructor)**
19+
* Copy constructor
20+
* Destructor
21+
* Copy assignment operator
22+
23+
For a class C, the copy constructor takes one parameter: const reference to object.
24+
25+
```cpp
26+
class C {
27+
public:
28+
C(const C &other) {}; //convention is to use other or rhs (right hand side)
29+
}
30+
```
31+
32+
An example of this is shown with the Student class:
33+
34+
```cpp
35+
class Student {
36+
private:
37+
int assignments;
38+
int midterm;
39+
int final;
40+
public:
41+
Student(const Student &other)
42+
: assignments(other.assignment)
43+
, midterm(other.midterm)
44+
, final(other.final) {}
45+
}
46+
```
47+
48+
The copy constructor shown above is the same behavior as the built-in copy constructor.
49+
50+
Consider the following:
51+
52+
```cpp
53+
class Node {
54+
private:
55+
int data;
56+
Node *next;
57+
public:
58+
Node(int data, Node *next)
59+
: data(data)
60+
, next(next)
61+
{}
62+
Node(const Node &other)
63+
: data(other.data)
64+
, next(other.next)
65+
{}
66+
};
67+
68+
Node *np = new Node(1, new Node(2, newNode(3, nullptr)));
69+
Node m = *np; //copy constructor
70+
Node *npCopy = new Node(*np); //copy constructor
71+
72+
//68: np[-]--> [1|-]--> [2|-]--> [3|/]
73+
//69: m[1|-]-------------^ points to *np's next instead of doing a deep copy
74+
//70: npCopy[-]-->[1|-]--^ similarly, points to *np's next
75+
```
76+
77+
The default copy constructor does a shallow copy.
78+
79+
We often want a "deep copy" when an object contains fields that are dynamically allocated (i.e. on the heap).
80+
81+
What we should do is the following:
82+
83+
```cpp
84+
class Node {
85+
private:
86+
int data;
87+
Node *next;
88+
public:
89+
Node(const Node &other) {
90+
this->data = other.data;
91+
if (other.next == nullptr) {
92+
this->next = nullptr;
93+
} else {
94+
// Need to dereference, we send in a Node object.
95+
this->next = new Node(*(other.next));
96+
}
97+
}
98+
}
99+
```
100+
101+
This will do a deep copy of the linked list.
102+
103+
We show an alternative way of writing the copy constructor:
104+
105+
```cpp
106+
class Node {
107+
private:
108+
int data;
109+
Node *next;
110+
public:
111+
Node(const Node &other)
112+
: data(other.data)
113+
, next(other.next ? new Node(*(other.next)) : nullptr)
114+
{}
115+
}
116+
```
117+
118+
Places where a copy constructor is called:
119+
120+
1. Creating an object as a copy of another
121+
2. When an object is passed by value
122+
3. When an object is returned by value (returning a stack allocated object)
123+
124+
We must pass in a const reference to a copy constructor.
125+
126+
This is because if we pass in the object by value, the copy constructor will be invoked each time.
127+
128+
### Single Parameter Constructors
129+
130+
```cpp
131+
class Node {
132+
public:
133+
Node(int data)
134+
: data(data)
135+
, next(nullptr)
136+
{}
137+
}
138+
139+
void foo(Node n) {}
140+
141+
Node n(4); // valid
142+
foo(n); // valid
143+
144+
Node m = 4; // valid
145+
foo(4); // valid
146+
```
147+
148+
Single Parameter Constructors create implicit conversions.
149+
150+
```
151+
string str = "hello";
152+
```
153+
154+
`std::string` has a 1 parameter constructor
155+
156+
Does an implicit conversion from `const char * --> std::string`
157+
158+
We can use the `explicit` keyword to disable this behavior.
159+
160+
```cpp
161+
class Node {
162+
public:
163+
explicit Node(int data)
164+
: data(data)
165+
, next(nullptr)
166+
{}
167+
}
168+
```
169+
170+
Now this will make
171+
172+
```cpp
173+
Node m = 4; // invalid
174+
foo(4); // invalid
175+
```
176+
177+
## Destructor
178+
179+
When an object is destroyed, a special method called the destructor runs.
180+
181+
Stack allocated object is destroyed when it goes out of scope.
182+
183+
Heap allocated object is destroyed when it is deleted.
184+
185+
* A class only has one destructor
186+
* 0 parameter method (no return type)
187+
188+
The name of a destructor is the name of the class prefixed with ~.
189+
190+
* You get a built-in destructor with every class.
191+
* Calls the destructor on any fields that are objects
192+
193+
```cpp
194+
Node *np = ...;
195+
196+
// np -->[1|-]-->[2|-]-->[3|/]
197+
198+
delete np;
199+
200+
struct Node {
201+
int data;
202+
Node *next;
203+
~Node() {
204+
delete next;
205+
}
206+
}
207+
```
208+
209+
Calling delete on `NULL` is safe.
210+
211+
The call to a `nullptr` will be what terminates the recursive execution of the destructor.
212+
213+
## Separate Compilation
214+
215+
**Recall**: we split our programs into
216+
217+
.h files (type definitions) .cc files (function implementations)
218+
219+
In the header files, we should now include method headers.
220+
221+
In the implementation files, we now should include method implementations.
222+
223+
The way we implement methods is by using this notation:
224+
225+
```cpp
226+
(Class name)::(Method name)() {}
227+
228+
Node::Node() {}
229+
void Node::push(int val) {}
230+
int Node::pop() {}
231+
...
232+
etc.
233+
```
234+
235+
## Assignment Operator
236+
237+
`Student bobby(billy);` copy constructor
238+
239+
`Student jane;` 0 parameter constructor
240+
241+
`jane = billy` updating an existing object to be a copy of the existing object

Midterm.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Midterm - Oct. 29, 2015
2+
3+
On the exam:
4+
5+
Preprocessor
6+
7+
Separate Compilation
8+
9+
Constructor
10+
11+
Copy constructor
12+
13+
Shell script (Similar to runSuite)
14+
15+
- Shell
16+
- Linux File System, Special Directories
17+
- cd, pwd, ls, echo, rm,
18+
- Globbing patterns
19+
- cat
20+
- Input/Output Redirection
21+
- Pipes
22+
- egrep
23+
- File Permissions (chmod)
24+
- Shell Variables ($PATH)
25+
- Shell Scripts
26+
- Command Line Arguments to a script
27+
- $#, $?, /dev/null, $0
28+
- script functions
29+
- if statement
30+
- While loop
31+
- for loop
32+
- Testing
33+
- C++
34+
- Hello World
35+
- Compiling/Executing C++ programs
36+
- Stream Objects (cin, cout, cerr)
37+
- I/O Operators (>>, <<)
38+
- cin.fail(), cin.eof()
39+
- implicit conversion of a stream to void* (e.g. cin to void*)
40+
- << and >> are binary operators: must produce an expression
41+
- << and >> cascading
42+
- cin.ignore(), cin.clear()
43+
- std::string
44+
- Semantics of reading from cin
45+
- I/O Manipulators: hex, dec, showpoint, setprecision , boolalpha, header <iomanip>
46+
- Stream Abstraction for files
47+
- header <fstream>, ifstream, ofstream
48+
- when is a file opened, when is it closed
49+
- Stream abstraction for strings
50+
- header <sstream>, istringstream, ostringstream
51+
- Converting a string to an integer
52+
- comparison between readInts5.cc and readsIntSS.cc
53+
- Strings in C++
54+
- std::string is not the same as a c-style string
55+
- string operations: concat, length, comparisons, length
56+
- Default Arguments
57+
- Function Overloading
58+
- Review: Declaration Before Use
59+
- Review: Pointers
60+
- Review: Arrays
61+
- Structs in C vs structs in C++
62+
- Review: Constants (see review slides 1151/lectures/ReviewSlides)
63+
- Review: Passing by Value, Passing a pointer (see review slides 1159/lectures/ReviewSlides)
64+
- References
65+
- Things you can and cannot do with references
66+
- Pass by reference
67+
- Why does cin >> x work in C++ when in C we had to do scanf("%s",&x)
68+
- Pass by Value vs Passing a pointer vs Pass by reference: pros and cons of each
69+
- Dynamic Memory Allocation: new and delete
70+
- Review Slides: Stack vs Heap Allocation
71+
- Operator Overloading
72+
- Examples: Vec, Grade
73+
- The C and C++ Preprocessor
74+
- #include: copy and paste
75+
- #define: search and replace
76+
- Using #define for Conditional Compilation (OS example, DEBUG example)
77+
- Separate Compilation (lectures/c++/separate)
78+
- C++ Classes
79+
- What is a class, what is an object, what are "functions" inside classes
80+
- Distinction between functions and methods
81+
- Initializing Objects
82+
- C Style Initialization
83+
- Constructors
84+
- Built-in 0 parameter ctor
85+
- Initializing const and reference fields
86+
- Steps that occur when an object is created
87+
- Member Initialization List (MIL)
88+
- Advantages of MIL
89+
- Copy Ctor
90+
- default ctor (shallow copy)
91+
- deep copy ctor
92+
- When to use deep copy
93+
- Places where a copy ctor is called

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ Lecture 10 - Dynamic Memory, Operators, Preprocessor
2525
Lecture 11 - Preprocessor Part II, Separate Compilation
2626

2727
Lecture 12 - C++ Objects
28+
29+
Lecture 13 - Copy Constructor, Destructor, Assignment Operator

0 commit comments

Comments
 (0)