15-interfaces-invariants.student

15-interfaces-invariants.student - Last Time: * Subtyping...

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

View Full Document Right Arrow Icon
Last Time: * Subtyping via method redefinition: overriding * Subclassing but not subtyping * Apparent vs. Actual types Today: * Virtual: Static vs. Dynamic type information * Hiding implementation details - Abstract Base Classes - Pure virtual methods * Providing an implementation * Representation invariants revisited * Coding the Rep Invar * Defensive programming ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ PosIntSet s; IntSet* p = &s; IntSet& r = s; Because PosIntSet is a subclass of IntSet, it is perfectly legal to make these assignments, and the compiler won't utter a peep when it sees this code. We have three variables: s is a PosIntSet, and p is a pointer that points to precisely this PosIntSet, and r is a reference to this PosIntSet. The following code: try { s.insert(-1); } catch (int i) { cout << "Exception thrown\n"; } Will do exactly what you expect: it will print "Exception thrown\n". However, what will the following code do? try { r.insert(-1); } catch (int i) { cout << "Exception thrown\n"; } At the point this line of code is compiled, the type of r is declared to be "reference to an IntSet", even though the thing r refers to happens to be a PosIntSet. Thus, the *apparent type* and the *actual type* differ. Apparent type: the declared type of the reference Actual type: the real type of the referent Note: even if the compiler "sees" the assignment, it does not assume it knows "more than" the declaration. In this example, the fact that r=s does not change the apparent type of r.
Background image of page 1

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

View Full DocumentRight Arrow Icon
As it happens, C++ *statically* chooses the method to run based on what it knows at compile time---in other words, methods are chosen based on apparent type. Because r's apparent type is "reference-to-IntSet", this code calls IntSet::insert(), which happily inserts -1 into the set referred to by r. The same thing happens if we use the pointer p, rather than the reference r This happens to break the representational invariant of the set s, which is Very Bad. There are kinds of properties that can be known about some variable/statement/etc. Static: known to the compiler *before* the program executes Dynamic: cannot be known statically, but can be learned only at run-time. Unfortunately, it is impossible (in general) to statically know the actual type of a reference. To see why, think about the following function: void foo(IntSet &bar); That is called from two different places: IntSet s; PosIntSet p; foo(s); foo(p); The same reference refers both to an IntSet *and* a PosIntSet at different times. So, since we can't know it statically, that leaves dynamically---but by
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 / 6

15-interfaces-invariants.student - Last Time: * Subtyping...

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