CS247 Lecture 5
- Last time: Dtor, Move ctor, copy/move assignment operator, elision: CS247 Lecture 4
- This Time: Improving encapsulation, iterators.
How can the client misuse this ADT: Tampering and Forgery?
Forgery:
Mostly likely a segmentation-fault on any kind of use.
Tampering:
All these issues are from a common problem: Representation exposure Every ADT has a representation in memory .
- e.g. Linked lists are implemented via a series of
Nodes
. If the client gains access to the memory, we call that representation exposure. (Client can use this knowledge to do things we don’t expect.)
We have expectations/rules for all linked lists:
- All next nodes are heap allocated (or next is nullptr)
- No sharing between separated lists
- No cycles in our list Clients shouldn’t need to uphold these invariants, it’s our responsability.
Solution: Encapsulation, provide public methods for the client to interact with our List with.
This solves our representation exposure problem. Client has no knowledge of Nodes, no access to internal memory representation, no tampering or forgery allowed. Lists are slow!
- ith is not a constant time operation!
- Takes i steps to find the i-th node in the List
for (i = 0; i < 100000; ++i) cout << l.ith(0)
Total:
We can’t just give clients access to Nodes again, representation exposure.
Design Patterns: Effective solutions to common problems. Problem: Efficient looping over a data structure while maintaining encapsulation. Pattern: Iterator Design Pattern: provide an abstraction for ptrs.
Example:
Our clients use of an iterator will look like:
For List: begin/end
functions that return iterators:
For List::Iterator
:
!=
to compare++
to go to the next Node*
to get the string at current Node
Implementation: (defined in .h)
If your implement an iterator like this, we can use the range-based for loop syntax: (shortcut syntax)
[!=Note] No reference ⇒ a copy from cur→data into S.
Can also use auto for type deduction:
Danger
Auto drops references, so if you want to modify l, use
auto&
.
Iterator is a public nested class, with a public ctor. Worry for Forgery:
auto it = List::Iterator{nullptr};
- creating an ending iterator
This could be a problem for other kinds of Iterators where nullptr
is not used.
Solution:
friend List
is a friend class- In general: cautious when using friends, weakens encapsulation.
- Only make friends if they can do something for you!
Subtle issue:
Doesn’t compile! because l is a constant value
- How should we know begin/end won’t modify the fields of this constant
l
?
Solution: Declare begin/end as const
methods, promise we won’t modify fields.
A constant object (or const reference to an object) may only have const methods called on it.
Now it compiles. (actually bad)
physical vs logical constness??
Next: