Data Types C++ Tutorial

/* The following code example is taken from the book
 * "The C++ Standard Library - A Tutorial and Reference"
 * by Nicolai M. Josuttis, Addison-Wesley, 1999
 *
 * (C) Copyright Nicolai M. Josuttis 1999.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
#include 
#include 
#include 
#include 
using namespace std;
/* class for counted reference semantics
 * - deletes the object to which it refers when the last CountedPtr
 *   that refers to it is destroyed
 */
template 
class CountedPtr {
  private:
    T* ptr;        // pointer to the value
    long* count;   // shared number of owners
  public:
    // initialize pointer with existing pointer
    // - requires that the pointer p is a return value of new
    explicit CountedPtr (T* p=0)
     : ptr(p), count(new long(1)) {
    }
    // copy pointer (one more owner)
    CountedPtr (const CountedPtr& p) throw()
     : ptr(p.ptr), count(p.count) {
        ++*count;
    }
    // destructor (delete value if this was the last owner)
    ~CountedPtr () throw() {
        dispose();
    }
    // assignment (unshare old and share new value)
    CountedPtr& operator= (const CountedPtr& p) throw() {
        if (this != &p) {
            dispose();
            ptr = p.ptr;
            count = p.count;
            ++*count;
        }
        return *this;
    }
    // access the value to which the pointer refers
    T& operator*() const throw() {
        return *ptr;
    }
    T* operator->() const throw() {
        return ptr;
    }
  private:
    void dispose() {
        if (--*count == 0) {
             delete count;
             delete ptr;
        }
    }
};
void printCountedPtr (CountedPtr elem)
{
    cout << *elem << ' ';
}
int main()
{
    // array of integers (to share in different containers)
    static int values[] = { 3, 5, 9, 1, 6, 4 };
    // two different collections
    typedef CountedPtr IntPtr;
    deque coll1;
    list coll2;
    /* insert shared objects into the collections
     * - same order in coll1
     * - reverse order in coll2
     */
    for (int i=0; i        IntPtr ptr(new int(values[i]));
        coll1.push_back(ptr);
        coll2.push_front(ptr);
    }
    // print contents of both collections
    for_each (coll1.begin(), coll1.end(),printCountedPtr);
    cout << endl;
    for_each (coll2.begin(), coll2.end(),printCountedPtr);
    cout << endl << endl;
    /* modify values at different places
     * - square third value in coll1
     * - negate first value in coll1
     * - set first value in coll2 to 0
     */
    *coll1[2] *= *coll1[2];
    (**coll1.begin()) *= -1;
    (**coll2.begin()) = 0;
    // print contents of both collections again
    for_each (coll1.begin(), coll1.end(),printCountedPtr);
    cout << endl;
    for_each (coll2.begin(), coll2.end(),printCountedPtr);
    cout << endl;
}
3 5 9 1 6 4
4 6 1 9 5 3
-3 5 81 1 6 0
0 6 1 81 5 -3