Arrays of Objects – Arrays of English Distances

We’ve seen how an object can contain an array. We can also reverse that situation and create an arrays of objects. We’ll look at two situations: an array of English distances and a deck of cards.

Arrays of English Distances

“Objects and Classes,” we showed several examples of an English Distance class that incorporated feet and inches into an object representing a new data type. The next program, ENGLARAY, demonstrates an array of such objects.

// englaray.cpp
// objects using English measurements
#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////
class Distance //English Distance class
{
private:
int feet;
float inches;
public:
void getdist() //get length from user
{
cout << “\n Enter feet: “; cin >> feet;
cout << “ Enter inches: “; cin >> inches;
}
void showdist() const //display distance
{ cout << feet << “\’-” << inches << ‘\”’; }
};
////////////////////////////////////////////////////////////////
int main()
{
Distance dist[100]; //array of distances
int n=0; //count the entries
char ans; //user response (‘y’ or ‘n’)
cout << endl;
do { //get distances from user
cout << “Enter distance number “ << n+1;
dist[n++].getdist(); //store distance in array
cout << “Enter another (y/n)?: “;
cin >> ans;
} while( ans != ‘n’ ); //quit if user types ‘n’
for(int j=0; j<n; j++) //display all distances
{
cout << “\nDistance number “ << j+1 << “ is “;
dist[j].showdist();
}
cout << endl;
return 0;
}

In this program the user types in as many distances as desired. After each distance is entered, the program asks if the user desires to enter another. If not, it terminates, and displays all the distances entered so far. Here’s a sample interaction when the user enters three distances:

Enter distance number 1
Enter feet: 5
Enter inches: 4
Enter another (y/n)? y
Enter distance number 2
Enter feet: 6
Enter inches: 2.5
Enter another (y/n)? y
Enter distance number 3
Enter feet: 5
Enter inches: 10.75
Enter another (y/n)? n
Distance number 1 is 5’-4”
Distance number 2 is 6’-2.5”
Distance number 3 is 5’-10.75”

Of course, instead of simply displaying the distances already entered, the program could have averaged them, written them to disk, or operated on them in other ways.

Array Bounds

This program uses a do loop to get input from the user. This way the user can input data for as many structures of type part as seems desirable, up to MAX, the size of the array (which is set to 100).

Although it’s hard to imagine anyone having the patience, what would happen if the user entered more than 100 distances? The answer is, something unpredictable but almost certainly bad. There is no bounds checking in C++ arrays. If the program inserts something beyond the end of the array, neither the compiler nor the runtime system will object. However, the renegade data will probably be written on top of other data or the program code itself. This may cause bizarre effects or crash the system completely.

if( n >= MAX )
{
cout << “\nThe array is full!!!”;
break;
}

This causes a break out of the loop and prevents the array from overflowing.

Accessing Objects in an Array

The declaration of the Distance class in this program is similar to that used in previous programs. However, in the main() program we define an array of such objects:

Distance dist[MAX];

Here the data type of the dist array is Distance, and it has MAX elements. Figure shows what this looks like.

A class member function that is an array element is accessed similarly to a structure member that is an array element, as in the PARTARAY example. Here’s how the showdist() member function of the jth element of the array dist is invoked:

dist[j].showdist();

As you can see, a member function of an object that is an array element is accessed using the dot operator: The array name followed by the index in brackets is joined, using the dot operator, to the member function name followed by parentheses. This is similar to accessing a structure (or class) data member, except that the function name and parentheses are used instead of the data name.

Notice that when we call the getdist() member function to put a distance into the array, we take the opportunity to increment the array index n:

dist[n++].getdist();

This way the next group of data obtained from the user will be placed in the structure in the next array element in dist. The n variable must be incremented manually like this because we use a do loop instead of a for loop. In the for loop, the loop variable which is incremented automatically can serve as the array index.

Arrays of Cards

Here’s another, somewhat longer, example of an arrays of objects. You will no doubt remember the CARDOBJ example from Chapter 6. We’ll borrow the card class from that example, and group an array of 52 such objects together in an array, thus creating a deck of cards. Here’s the listing for CARDARAY:

// cardaray.cpp
// cards as objects
#include <iostream>
#include <cstdlib>     //for srand(), rand()
#include <ctime>      //for time for srand()
using namespace std;
enum Suit { clubs, diamonds, hearts, spades };
//from 2 to 10 are integers without names
const int jack = 11;
const int queen = 12;
const int king = 13;
const int ace = 14;
////////////////////////////////////////////////////////////////
class card
{
private:
int number; //2 to 10, jack, queen, king, ace
Suit suit; //clubs, diamonds, hearts, spades
public:
card() //constructor
{ }
void set(int n, Suit s) //set card
{ suit = s; number = n; }
void display(); //display card
};
//--------------------------------------------------------------
void card::display() //display the card
{
if( number >= 2 && number <= 10 )
cout << number;
else
switch(number)
{
case jack: cout << “J”; break;
case queen: cout << “Q”; break;
case king: cout << “K”; break;
case ace: cout << “A”; break;
}
switch(suit)
{
case clubs: cout << static_cast(5); break;
case diamonds: cout << static_cast(4); break;
case hearts: cout << static_cast(3); break;
case spades: cout << static_cast(6); break;
}
}
////////////////////////////////////////////////////////////////
int main()
{
card deck[52];
int j;
cout << endl;
for(j=0; j<52; j++) //make an ordered deck
{
int num = (j % 13) + 2; //cycles through 2 to 14, 4 times
Suit su = Suit(j / 13); //cycles through 0 to 3, 13 times
deck[j].set(num, su); //set card
}
cout << “\nOrdered deck:\n”;
for(j=0; j<52; j++) //display ordered deck
{
deck[j].display();
cout << “ “;
if( !( (j+1) % 13) ) //newline every 13 cards
cout << endl;
}
srand( time(NULL) ); //seed random numbers with time
for(j=0; j<52; j++) //for each card in the deck,
{
int k = rand() % 52; //pick another card at random
card temp = deck[j]; //and swap them
deck[j] = deck[k];
deck[k] = temp;
}
cout << “\nShuffled deck:\n”;
for(j=0; j<52; j++) //display shuffled deck
{
deck[j].display();
cout << “, “;
if( !( (j+1) % 13) ) //newline every 13 cards
cout << endl;
}
return 0;
} //end main

Once we’ve created a deck, it’s hard to resist the temptation to shuffle it. We display the cards in the deck, shuffle it, and then display it again. To conserve space we use graphics characters for the club, diamond, heart, and spade. Figure shows the output from the program. This program incorporates several new ideas, so let’s look at them in turn.

output

Graphics Characters

There are several special graphics characters in the range below ASCII code 32. (See Appendix A, “ASCII Table,” for a list of ASCII codes.) In the display() member function of card we use codes 5, 4, 3, and 6 to access the characters for a club, a diamond, a heart, and a spade, respectively. Casting these numbers to type char, as in static_cast(5)

causes the << operator to print them as characters rather than as numbers.

The Card Deck

The array of structures that constitutes the deck of cards is defined in the statement card deck[52]; which creates an array called deck, consisting of 52 objects of type card. To display the jth card in the deck, we call the display() member function: deck[j].display();

Random Numbers

It’s always fun and sometimes even useful to generate random numbers. In this program we use them to shuffle the deck. Two steps are necessary to obtain random numbers. First the random number generator must be seeded, or initialized. To do this we call the srand() library function. This function uses the system time as the seed, so it requires two header files, CSTDLIB and CTIME.

To actually generate a random number we call the rand() library function. This function returns a random integer. To get a number in the range from 0 to 51, we apply the remainder operator and 52 to the result of rand().

int k = rand() % 52;

The resulting random number k is then used as an index to swap two cards. We go through the for loop, swapping one card, whose index points to each card in 0-to-51 order, with another card, whose index is the random number. When all 52 cards have been exchanged with a random card, the deck is considered to be shuffled. This program could form the basis for a card playing program, but we’ll leave these details for you.

Arrays of objects are widely used in C++ programming. We’ll see other examples as we go along.

Read More Topics
Arrays in C language
Array structures and unions in C
Arrays programming

About the author

Santhakumar Raja

Hi, This blog is dedicated to students to stay update in the education industry. Motivates students to become better readers and writers.

View all posts

Leave a Reply