Recently, I have been reading about the Effective STL by Scott Meyers and must read book if we want to write a good re-usable code still following best practices. This article reviews Item-2 chapter of the effective STL book.
Pre-requisite: Basic understanding of STL, Type definitions, Classes in C++
Track: Advanced C++, Design principles.
Idea of Generalization:
We know the whole concept of object oriented programming is to write a piece of code which encapsulates all low level features under the hood. For instance, simple functions can be generalized as algorithms and Arrays can be generalized into containers and so on. However, can we write a code to generalize container and hide them implicitly.
Short answer: For the former it’s difficult(useless) but for the later it is possible.
Code to Generalize container:
Just highlighting the differences between the sequence and associative container draws the below table:
|Sequence Container (vector, deque, list)||Associative Container (map, set)|
|•Push_front, push_back||•No support|
|•No support||•Time complexity: logarthimic for using
The above table clearly draws the line between the sequence and associative containers…
So, How about we then Generalize within only Sequence containers?
Answer is Nope!
Because, lot vary between within sequence containers.
Such as List supports only Bi-directional iterators leaving out all usage of algorithms using Random access iterators.
So, finally can we wrap up and restrict only for the Associative containers- Sorry, still no!
Since, a rational to generalize sets and maps is nearly impossible as one uses single object and other uses the multiple object.
So, it is very clear that our wish to generalize the container is impossible. But, how can we still write good software hiding or generalizing a container apart from the code.
Answer is use Encapsulation, encapsulation, encapsulation and encapsulation!(Ok that’s too much of emphasis)
Let us say we have class:
Can we now re-write:
typedef Vector<Widget> WidgetContainer;
Ok, wait.. we all know how to encapsulate and hide things !
Still, what’s the point….?
Use typedef (encapsulation) to enable write us container independent re-usable and maintainable code. Period!
Now, lets us say we have a:
typedef list<Customer> CustomerContainer;
typedef CustomerContainer::iterator Cciterator;
In the above code, the class hides all the internal implementation of the container hidden within itself yet the class straight forwardly is a list.
[Roll on.. Many years.. say 2025-hope c++ survives]
We realize that we no longer need to support the insert a customer at the middle. But, a new requirement to find the top 20% of the customers present comes in.
So, how do we then handle this new requirement still or without depreciating old functionality. We use n_th element algorithm but we need to change the container to vector or deque. Hence, this gives us the freedom to not bother about implementation of the container inside our code.
Yay, we did a good job! we had encapsulated a container which can be changed based on the requirements still its is done implicitly. So, to conclude to write complete container independent code is nearly impossible.
However, we could hide and do good job of encapsulating the implementation of container from the code and maintain them for future use.