AN OBJECT WITH AN INTERNAL POINTER

The program named OBJINTPT.CPP is our first example program with an embedded pointer which will be used for dynamic allocation of data.

// objintpt.cpp
#include <iostream.h>

class box {
int length;
int width;
int *point;
public:
box(void); //Constructor
void set(int new_length, int new_width, int stored_value);
int get_area(void) {return length * width;} // Inline
int get_value(void) {return *point;} // Inline
~box(); //Destructor
};

box::box(void) //Constructor implementation
{
length = 8;
width = 8;
point = new int;
*point = 112;
}

// This method will set a box size to the input parameters
void box::set(int new_length, int new_width, int stored_value)
{
length = new_length;
width = new_width;
*point = stored_value;
}

box::~box(void) //Destructor
{
length = 0;
width = 0;
delete point;
}

main()
{
box small, medium, large; //Three boxes to work with

small.set(5, 7, 177);
large.set(15, 20, 999);

cout << "The small box area is " << small.get_area() << "\n";
cout << "The medium box area is " << medium.get_area() << "\n";
cout << "The large box area is " << large.get_area() << "\n";
cout << "The small box stored value is " <<
small.get_value() << "\n";
cout << "The medium box stored value is " <<
medium.get_value() << "\n";
cout << "The large box stored value is " <<
large.get_value() << "\n";
}

// Result of execution
//
// The small box area is 35
// The medium box area is 64
// The large box area is 300
// The small box stored value is 177
// The medium box stored value is 112
// The large box stored value is 999

In line 7 we declare a pointer to an integer variable, but it is only a pointer, there is no storage associated with it. The constructor therefore allocates an integer type

variable on the heap for use with this pointer in line 21. It should be clear to you that the three objects created in line 45 each contain a pointer which points into the heap to three different locations. Each object has its own dynamically allocated variable for its own private use. Moreover each has a value of 112 stored in its dynamically allocated data because line 22 stores that value in each of the three locations, once for each call to the constructor.

In such a small program, there is no chance that we will exhaust the heap, so no test is made for unavailable memory. In a real production program, it would be expedient to test that the value of the returned pointer is not NULL to assure that the data actually did get allocated.

The method named set() has three parameters associated with it and the third parameter is used to set the value of the new dynamically allocated variable. There are two messages passed, one to the small box and one to the large box. As before, the medium box is left with its default values.

The three areas are displayed followed by the three stored values in the dynamically allocated variables, and we finally have a program that requires a destructor in order to be completely proper. If we simply leave the scope of the objects as we do when we leave the main program, we will leave the three dynamically allocated variables on the heap with nothing pointing to them. They will be inaccessible and will therefore represent wasted storage on the heap. For that reason, the destructor is used to delete the variable which the pointer named point is referencing as each object goes out of existence. In this case, lines 37 and 38 assign values to variables that will be automatically deleted. Even though these lines of code really do no good, they are legal statements.

Actually, in this particular case, the variables will be automatically reclaimed when we return to the operating system because all program cleanup is done for us at that time. If this were a function that was called by another function however, the heap space would be wasted. This is an illustration of good programming practice, that of cleaning up after yourself when you no longer need some dynamically allocated variables.

One other construct should be mentioned once again, that of the inline method implementations in line 11 and 12. As we mentioned in chapter 5 and repeated earlier in this chapter, inline functions can be used where speed is of the utmost in importance since the code is assembled inline rather than by actually making a method call. Since the code is defined as part of the declaration, the system will assemble it inline, and a separate implementation for these methods is not needed. If the inline code is too involved, the compiler is allowed to ignore the inline request and will actually assemble it as a separate method, but it will do it invisibly to you and will probably not even tell you about it. Remember that we are interested in using information hiding and inline code prevents hiding of the implementation, putting it out in full view. Many times you will be more interested in speeding up a program than you are in hiding a trivial implementation. Since most inline methods are trivial, feel free to use the inline code construct.

Be sure to compile and execute this program.