21-polymorphism-and-bugs.student - Last Time: *...

Info iconThis preview shows pages 1–3. Sign up to view the full content.

View Full Document Right Arrow Icon
Last Time: * Double-ended lists * Doubly-linked lists * The "at-most-once" rule * Templates Today: * Containers-by-reference vs. by-value * Run-time polymorphism ++++++++++++++++++++++++++++++++= If you've been paying close attention, you'll notice that we've danced around the issue of how BigThings are handled: List<BigThing> *lbtp = new List<BigThing>; vs. List<BigThing *> *lbtp = new List<BigThing *>; There are several reasons for this. The most important such reason is that there is a fundamental difference between containers-of-objects and containers-of-pointers---the latter are subject to two broad classes of potential bugs: * using an object after it has been deleted * leaving an object orphaned by *never* deleting it We have introduced the "at-most-once" invariant to avoid the vast majority of these sorts of bugs. The invariant has a simple statement, plus three rules-of-thumb to ensure that it is maintained: at-most-once: a pointer to any specific object can exist in at most one container object at any point in time. The three rules were: Existence: an object must be dynamically allocated before a pointer to it is inserted. Ownership: once a pointer to an object is inserted, that object becomes the property of the container. No one else may use or modify it in any way. Conservation: when a pointer is removed from a container, either the pointer must be inserted into *some* container, or it's referent must be deleted. These rules have an important implication for any method that destroys an existing container. There are (at least) two such methods: * The destructor: destroys an existing instance. * The assignment operator: destroys an existing instance before copying the contents of another instance.
Background image of page 1

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon
For example, consider the following implementation of the destructor for a singly-linked, simple list, using the interface we've discussed so far: template<class T> List<T>::~List() { while (!isEmpty()) { remove(); } } If this list stores things by pointer (i.e.: T is of type "pointer to something"), this implementation violates one of the three rules. Which one is violated, and how? To fix this, we *must* handle the objects we remove: List<T>::~List() { while (!isEmpty()) { T op = remove(); delete op; } } ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ The consequence of this is that the List template *must* know whether it is something that holds "Ts" or "pointers to T"---The former *cannot* delete values it held that are being destroyed, while the
Background image of page 2
Image of page 3
This is the end of the preview. Sign up to access the rest of the document.

This note was uploaded on 01/28/2010 for the course EECS 280 taught by Professor Noble during the Winter '08 term at University of Michigan.

Page1 / 8

21-polymorphism-and-bugs.student - Last Time: *...

This preview shows document pages 1 - 3. Sign up to view the full document.

View Full Document Right Arrow Icon
Ask a homework question - tutors are online