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:

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:



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