CS62 - Spring 2011 - Lecture 35
administrative
- keep looking at the exercises
A quick review of some terminology
- in Java we have two types of variables/values
- built-in types (int, double, float)
- references to objects
- in C++, we have three types
- built-in types
- pointers to objects (e.g. references to objects)
- int*
- vector<int>*
- BinaryTree*
- objects that are on the stack
- an "operator" is a special symbol that performs a specific operation on one, two or three operands and returns a result
- what operators have we seen?
- When dealing with pointers, we have three operators that come up:
- * dereferences a pointer and returns the actual object/value pointed to by the pointer
- int* x;
- *x (gives us the value pointed to by x)
- vector<int>* v
- *v (gives us the vector point to by v)
- -> accesses members of the object pointed to by the pointer
- vector<int>* v
- v->push_back(10)
- v->size()
- BinaryTree* b
- b->size()
- & gives us the memory location (or a reference to) where a variable is stored
vector<int> v;
vector<int>* vPtr = &v;
- parameter passing
- when calling a function, we have the actual parameters
- f(2, 3)
- f(2+5, 7)
- f(x, y)
- and we have the formal parameters
- f( int x, int y )
- f( vector<int>* x )
- parameter passing is how the actual parameters get bound to the formal parameters
- there are three types of parameter passing in C++:
- call by value
- the actual parameters get copied
- for built-in types, this just means copying the value
- for objects, this means calling the copy constructor and creating a new object
- call by reference
- the actual parameters and the formal parameters are the same thing
- rather than copying, the formal parameters become an alias (or another name) for the actual parameters
- this is denoted by placing an '&' after the type in the formal parameter list
- NOTE: this is DIFFERENT from the & operator
- the type is still the original type
- BinaryTree& is different than BinaryTree*
- call by constant reference
- same as above, except we can't modify the parameters in the method
- return approaches
- similarly, we can specify how things are returned from a function/method
look at
linkedlist.cpp code
- should be similar to the code you wrote in lab
- look at test2 in linkedlisttest.cpp
- what did your answer print out?
L: 9 8 7 6 5 100 3 2 1 0
L2: 9 8 7 6 5 100 3 2 1 0
- why?
- because we used the default copy constructor, which does a shallow copy of the data
- the default copy constructor would just copy the pointer value of head
- l and l2 would refer to the same chain of Nodes
- what if we wanted it to do a deep copy?
- add a copy constructor that traverses the Node chain and copies it
- look at
linkedlistimproved.cpp code
- added both the copy constructor and the = operator
- almost always if you add one, you're going to need the other
- look at the copy constructor... often we can reuse code
- look at the = operator
- clear (that is, empty) the linked list
- copy it over a node at a time
memory management
- in general, EVERY time you create an object on the heap using "new" you should make sure that you're calling delete appropriately somewhere else in your code
- memory management is hard!
- pitfalls
- memory leak (forgetting to delete an object)
- deleting memory before it's actually freed up
vector<int>* v = new vector<int>;
vector<int>* v2 = v;
delete v;
v2->push_back(10);
- look at example in
problems.cpp code
- what will this do/print out?
- double deleting memory
vector<int>* v = new vector<int>;
vector<int>* v2 = v;
delete v;
delete v2;
does our linked list code correctly handle memory?
- no!
write removeFirst() to correctly handle memory deletion
Can we use this method to write our clear method?
- look at clear() method in
linkedlistimproved.cpp code
- recursively removing elements from the list until it's empty
- look at removeFirst() method in
linkedlistimproved.cpp code