The objects instantiated from a class can be stored in various C++ containers in the same way containers store variables of the various built-in data types. In this article I'm going to show you how to store class objects in arrays and vectors and how to access those objects once they are stored away.

A Class Definition

The class I'm going to use to demonstrate how to store class objects in container is a Student class that has the student's name, their student id, and a vector with their grades for the term. It's especially important that I have a member variable that is itself a container so I can show you how to access the grades from inside another container (that just got confusing).

Here is the Student (nominal) class definition:

class Student {
private:
  string name;
  string id;
  vector<int> grades;
public:
  Student(string n, string i) {
    name = n;
    id = i;
  }
  Student() {
    name = "";
    id = "";
  }
  string getName() { return name; }
  string getId() { return id; }
  void addGrade(int grade) {
    grades.push_back(grade);
  }
};

Storing and Accessing Class Objects in an Array

Now let's create a few objects and put them in an array. The array is created by using the Student class as the data type followed by a name and the number of elements to store. Here is the line of code for that:

const int numStudents = 3;
Student students[numStudents];

Here is the complete program that uses the Student class definition:

int main ()
{
  Student stu1("Jane Smith", "1234");
  stu1.addGrade(77);
  stu1.addGrade(81);
  stu1.addGrade(88);
  Student stu2("John Jones", "2345");
  stu2.addGrade(91);
  stu2.addGrade(81);
  stu2.addGrade(66);
  Student stu3("Barb Green", "4321");
  stu3.addGrade(81);
  stu3.addGrade(82);
  stu3.addGrade(83);
  const int numStudents = 3;
  Student students[numStudents];
  students[0] = stu1;
  students[1] = stu2;
  students[2] = stu3;
  return 0;
}

Now let's see how to access the objects in the array to display their names and ids. If a Student object is not in a container, we can access the object name followed by the dot operator and the member function name we wanted. With the objects in an array, the object name is replaced with the array name and the index position we are accessing.

Here's a code fragment that demonstrates how to do this:

for (int i = 0; i < numStudents; i++) {
  cout << students[i].getName() << ", "
       << students[i].getId() << endl;
}

Here is the output when we run the program:

Jane Smith, 1234
John Jones, 2345
Barb Green, 4321

That wasn't too bad. Now let's go a level deeper and access the grades that are stored in the vector. Since the grades vector is private, we need a getter member function to retrieve the grades:

void showGrades() {
  for (int grade : grades) {
    cout << grade << " ";
  }
}

Now we can incorporate a call to this member function into our program:

for (int i = 0; i < numStudents; i++) {
  cout << students[i].getName() << ", "
       << students[i].getId() << endl;
  cout << "Grades: ";
  students[1].showGrades();
  cout << endl;
}

The output now is:

Jane Smith, 1234
Grades: 91 81 66
John Jones, 2345
Grades: 91 81 66
Barb Green, 4321
Grades: 91 81 66

Similarly, we could write member functions to calculate the grade average, find the lowest and highest grades, etc. But that's enough with arrays for now. Let's move on to vectors.

Storing and Accessing Class Objects in a Vector

The primary difference in using vectors for storing class objects versus using an array, other than all the differences between vectors and arrays, is how you declare the vector to store class objects.

We can use the same Student class definition as shown earlier. We can use the same object instantiation code we used earlier to create three students. The first change we have to make is to replace the array declaration statement with a statement creating a vector:

vector<Student> students;

We don't need a constant to represent the number of students because we can use the size member function if we need to know how many elements are in the vector, and since we can use a range for loop for traversing the vector, we don't need the constant for that loop.

The rest of our program can be used as we wrote it earlier. We will use the same dot notation to access the member functions of the object, replacing array notation (students[n]) with the vector name, such as when we add students to the vector:

students.push_back(stu1);
students.push_back(stu2);
students.push_back(stu3);

With those things in mind, here is the program for storing and accessing Student objects in a vector:

#include <iostream>
#include <vector>
using namespace std;
// class definition goes here
int main ()
{
  Student stu1("Jane Smith", "1234");
  stu1.addGrade(77);
  stu1.addGrade(81);
  stu1.addGrade(88);
  Student stu2("John Jones", "2345");
  stu2.addGrade(91);
  stu2.addGrade(81);
  stu2.addGrade(66);
  Student stu3("Barb Green", "4321");
  stu3.addGrade(81);
  stu3.addGrade(82);
  stu3.addGrade(83);
  vector<Student> students;
  students.push_back(stu1);
  students.push_back(stu2);
  students.push_back(stu3);
  for (Student stdnt : students) {
    cout << stdnt.getName() << ", " << stdnt.getId() << endl;
    cout << "Grades: ";
    stdnt.showGrades();
    cout << endl;
  }
  return 0;
}

Here is the output from the program:

Jane Smith, 1234
Grades: 77 81 88
John Jones, 2345
Grades: 91 81 66
Barb Green, 4321
Grades: 81 82 83

Class Dismissed

That's it for this overview on storing class objects in array and vector containers. In my next article, I'll move to a more technical yet useful topic — operator overloading.

Thanks for reading and please email me at mmmcmillan1@att.net with comments and suggestions. If you are interested in my online programming courses, please visit https://learningcpp.teachable.com.