The Array Class header file

The Array class introduces several new concepts:
  • a pointer data member and dynamic memory associated with an object
  • destructor
  • copy constructor
  • overloaded operator=
  • static members

    The header file   --   the whole thing: array.h

    The Array class is a wrapper for an int array. It retains all functionality of a regular int array but also allows you to do things you can't do with a regular int array. It
  • allows input and output of the whole array
  • allows for comparison of two arrays, element by element
  • allows for assignment of two arrays
  • size of the array is part of the class (like what's built in in Java)
  • includes range checking, program terminates for out-of-bound subscripts

    This header file is similar in format to the Rational class examples. The preprocessor statements and the using statement at the beginning of the .h file are similar (except a different identifier, ARRAY_H, to match the filename is used):
    #ifndef ARRAY_H
    #define ARRAY_H
    #include < iostream > 
    using namespace std;
    
    Consider the class definition. The private members:
       int* arrayPtr;   points to the first element of an array, 
       int size;   is the size of the array, and
       static int arrayCount;   is the number of Arrays instantiated.
    
    Static members
    The arrayCount member is static . Typically when you instantiate an object, each object owns every member. For example, if you have five Array objects, each has a size data member, for a total of five. Static members are different in that they are associated with the "class" of objects, not individual objects. Each "class" of objects owns one static member.
    The static member, arrayCount, will be used to count how many Array objects have been instantiated, i.e., how many Array objects have been declared. You can probably guess that any constructor will increase this count by one since a constructor gets called every time an Array object is instantiated.
    The two friend functions are identical to the Rational class friend functions except for the Array type:
       friend ostream& operator<<(ostream &, const Array &);
       friend istream& operator>>(istream &, Array &);
    
    Notice that the constructor has a default value on its one parameter. The constructor's parameter will be the size of the array (the value 10 was assigned arbitrarily):
       Array(int = 10);
    
    Copy constructor and destructor
    The next two functions are the copy constructor and destructor. Whenever your object has dynamic memory associated with it, you will need to write these.
       Array(const Array &); 
       ~Array();            
    
    Copy constructors are written to make an exact duplicate of another object. All copy constructors will look similar in format to this one. They are still a constructor, constructing a brand new object (so no return type). The parameter will always be an object of the same type as the class; it's the object that is being duplicated.

    The destructor is written to deallocate any memory that was dynamically allocated associated with the object. Typically every class that has a pointer as a data member has a constructor that will allocate memory for that pointer and a destructor that will deallocate (or delete) that memory. If you don't deallocate the memory, then a memory leak occurs. If this memory is not deallocated, then it can never be used by you again. If you consistently allocate memory, but don't deallocate it, you will run out of memory. Very bad!

    Member functions - old stuff
       int getSize() const;                    
       bool operator==(const Array &) const;  
       bool operator!=(const Array &) const; 
    
    Nothing new here. The getSize() returns the size of the array. The overloaded operator== and operator!= are similar to operator+ of the Rational class.

    Member functions - operator=, operator[], getArrayCount
       const Array& operator=(const Array &);  
       int& operator[](int);  
       static int getArrayCount();   
    
    The overloaded operator= now has to be written because when you have dynamic memory, the default operator= (which does a memberwise copy of data and functions) isn't sufficient. New memory needs to be allocated.

    Remember this is called when you do something like   a = b;   The parameter is always an object of the type of the class since you're copying its values (the righthand side of the assignment) into the current object (the lefthand side of the assignment). This is similar in task to the copy constructor except with the copy constructor, you're creating a brand new object. The operator= is replacing an existing object with a different one.

    Because you're simply replacing an existing object with a different one, the return type can be a reference, const Array&. You may as well return the address (for efficiency) instead of making a copy of the whole thing. This is similar to using const Array& as a parameter. You pass the address of the thing instead of making a copy of it.

    The function operator[] is actually called when you use [] on an Array object. When you use [] with an Array object, you do it because you're trying to simulate a regular old int array element. To the user of the class, this notation hides that it's a user-defined class. The return type is int& because you will use it in something like   obj[i] = 5;   Again, the lefthand side is getting changed (the return type), so it has to be a reference. The details of how this works are discussed when the .cpp file is discussed.

    the getArrayCount(); is static because it returns the number of arrays instantiated, returns the value of the static data member, arrayCount. If you only access other static members, then you make the function static. Having only one of them, that all objects can use, is sufficient. Each object doesn't need their own.