### Using Automatic Pointers

Automatic pointers should be used when the lifetime of the element is the same as the lifetime of the pointer, but when an explicit deletion of the element is awkward or even impossible. This applies in particular to pointers to objects that are dynamically created within a function, and whose lifetime is the scope of the function. The function may be left through several return statements or through an exception being thrown from some other function being called.

### Assigning One Automatic Pointer to Another

Using the assignment operator, the automatic pointer is used to point to another element (which is implicitly a new element). The assigned pointer is set to NULL.

### Holding Automatic Pointers in a Collection

If you define a collection taking automatic pointers as elements, the elements are automatically deleted when the collection is destructed, when an element is removed, or, if the element was not added to the collection, when the variable or temporary holding the pointer is destructed. The following example deletes all pointers that were added previously to the set with the destruction of the set:

    #include "person.h"   // Declaration of Person class
    #include <istdops.h>
    #include <iset.h>

    typedef IAutoElemPointer<Person> AEPointer;
    typedef ISet<AEPointer> AddressList;

    ostream& operator<<(ostream& os,Person A)
    {
       return (os << endl << A.GetPersonName() <<" "<<A.GetTNumber());
    }

    void main()
    {
        AddressList Business;
        AddressList::Cursor myCursor1(Business);

        Business.add(AEPointer (new Person("Peter Black","714-50706"),IINIT));
        Business.add(AEPointer (new Person("Carl Render","714-540321"),IINIT));
        Business.add(AEPointer (new Person("Sandra Summers","x"),IINIT));
        Business.add(AEPointer (new Person("Mike Summers","x"),IINIT));
        //The temporary automatic pointer variables were set to NULL
        //when the pointer was copied to the collection.

        //The following deletes the second Person ("Sandra ..."), because it
        //was not added (note that in a set, each element occurs only once).
        {
            Business.add(AEPointer (new Person("Sandra Summers","x"),IINIT));
        }

        forICursor(myCursor1) {
            cout << *Business.elementAt(myCursor1);
        }
    }

### Transferring Automatic Pointers Between Functions

You should be aware of the implementation details described below when transferring automatic pointers between functions. Consider the following cases:

#### Case 1: A calling function passes an automatic pointer to a called function and the pointer is returned.

The following code passes an automatic pointer to a called function and the pointer is returned.

    IAutoPointer<Int> someFunc(IAutoPointer<Int> autoIntPtr)
    {
        return autoIntPtr;
    }

    ...

    main ()
    {
        IAutoPointer<Int> myIntPtr(new Int(5), IINIT);
        cout << *someFunc(myIntPtr) << endl;
    }

This program results in the following taking place at runtime:

- The main function constructs an IAutoPointer object autoIntPtr and initializes it with the address of Int object 5 (where Int is a class that wraps an int).
- On invocation of someFunc, the copy constructor of IAutoPointer is called and the new constructed auto pointer is initialized with the address of the given input pointer. The given pointer is set to NULL. On return from someFunc, the copy constructor of IAutoPointer constructs a new auto pointer in main and initializes it with the address of the auto pointer object returned from someFunc, which then is destructed.
- When main exits, it calls the destructors for all auto pointer objects and the destructor for Int object 5.

#### Case 2: A called function has no input, but returns an object that has been dynamically created using an automatic pointer.

The following code returns an object that has been dynamically created using an automatic pointer.

    Int someFunc()
    {
        IAutoPointer<Int> autoIntPtr(new Int(6), IINIT);
        return *autoIntPtr;
    }

    ...

    main()
    {
        cout << someFunc() << endl;
    }

This program results in the following taking place at runtime:

- On invocation of someFunc, this function constructs an IAutoPointer object, constructs an Int(6) object, and initializes the auto pointer with the address of Int(6).
- On return from someFunc, the copy constructor of Int constructs a new Int(6) object in main. The auto pointer object and the Int(6) object in someFunc are destructed.
- On exit from main, the Int(6) object is destructed.

Introduction to the Collection Classes
Collection Class Hierarchy
Overall Implementation Structure
Adding Elements
Removing Elements
Replacing Elements
Smart Pointers

Choosing the Appropriate Smart Pointer Class
Constructing Smart Pointers
Using Element Pointers
Using Managed Pointers
Things to Watch Out For When Using Smart Pointers
Copying and Referencing Collections
Instantiating the Collection Classes