user1618639
user1618639

Reputation: 11

C++ Dynamic Array of objects

C++ newbie here and this is my first post. I am working on a project at school and I'm somewhat stuck. My task is to create a roster of courses. Each roster will contain a course name, course code, course credits, and professor name. No problem, I have a Roster class. The problem is I'm unsure how to make an array of objects dynamic, as it must be able to grow and shrink when requested by the user. I am somewhat familiar with dynamic arrays in general, but unsure of the syntax of dynamic arrays of objects. And, as per the professor's instructions, vectors are not an option. I've searched this forum as well as other areas on the internet and haven't found an answer, or I'm not understanding the answers I've found, and thought I'd post here. The following is my code for a non-dynamic array of objects. Help in converting to a dynamic array would be much appreciated. Thanks!

StudentEnrollment.h:

#ifndef STUDENTENROLLMENT_H
#define STUDENTENROLLMENT_H

# include <iostream>
# include <string>

using namespace std;

class Roster {

private:

    string courseName;
    string courseCode;
    string courseCredits;
    string professorName;

public:

    void setCourseName ( string );
    void setCourseCode ( string );
    void setCourseCredits ( string );
    void setProfessorName ( string );

    string getCourseName();
    string getCourseCode();
    string getCourseCredits();
    string getProfessorName();

    Roster ();

};

#endif;

StudentEnrollment.cpp:

#include <iostream>
#include <string>
#include "StudentEnrollment.h"

using namespace std;

// Roster class implementation

Roster::Roster () {

    courseName = "";
    courseCode = "";
    courseCredits = "";
    professorName = "";


}   


void Roster::setCourseName ( string cn ) {
    courseName = cn;
}

void Roster::setCourseCode ( string c ) {
    courseCode = c;
}

void Roster::setCourseCredits ( string cc ) {
    courseCredits = cc;
}

void Roster::setProfessorName ( string pn ) {
    professorName = pn;
}

string Roster::getCourseName() {
    return courseName;
}

string Roster::getCourseCode() {
    return courseCode;
}

string Roster::getCourseCredits() {
    return courseCredits;
}

string Roster::getProfessorName() {
    return professorName;
}

main.cpp:

#include <iostream>
#include <string>
#include "StudentEnrollment.h"

using namespace std;

int main (int argc, char * const argv[]) {

    int number_of_rosters = 0;

    string course, code, credits, name;

    cout << "Enter the number of rosters you would like to create: ";
    cin >> number_of_rosters;
    cin.ignore(100, '\n');


    Roster roster[number_of_rosters];

    for ( int i = 0; i < number_of_rosters; i++){
        cout << "Enter course name: ";
        getline(cin,course);
        roster[i].setCourseName(course);

        cout << "Enter course code; ";
        getline(cin, code);
        roster[i].setCourseCode(code);

        cout << "Enter course credits: ";
        getline(cin, credits);
        roster[i].setCourseCredits(credits);

        cout << "Enter professor name: ";
        getline(cin, name);
        roster[i].setProfessorName(name);

        cout << "Next course..." << endl;
    }

    cout << endl;

    for ( int i = 0; i < number_of_rosters; i++){
        cout << roster[i].getCourseName() << endl;
        cout << roster[i].getCourseCode() << endl;
        cout << roster[i].getCourseCredits() << endl;
        cout << roster[i].getProfessorName() << endl;
        cout << endl;
    }

    return 0;
}

Forgive me if this didn't format correctly. This is my first post.

Arthur

Upvotes: 1

Views: 3151

Answers (2)

Samy Vilar
Samy Vilar

Reputation: 11130

I think you are going to have to implement your own data structure, c++ really doesn't support this natively as far as I know, which is why we use vectors.

For this type of problems, where we have to implement our own data structures, I think a linklist would be an appropriate solution.

This is may be how vectors are implemented internally, their are different solutions.

Fundamentally a LinkList is a special data structure made of connected nodes, think of it as a chain where each element holds a value, in this case a roster, as well as a link to the next element and/or a link to the previous element and so on ... so if you want to add an element you can simply add it to the end or to the beginning its up to you, if you want to remove an element simply cut it and connect the two elements together, contrast with an array of objects which is more like a stick, you can't really add stuff to either ends and you can't really cut even if you could, you can really connected it back to together, seamlessly.

There are many variations to linklists but thats the gist of it.

On the other hand if you want to use dynamic arrays you are going to have manually copy all the values into the new larger array, and destroy the previous one, this is really expensive, and can be quite dangerous fundamentally you are going to need to implement a copy constructor we could use memcpy but this can be quite dangerous if our objects hold references or pointers to other objects, in which case if their deleted it we would be pointing to bad values.

Also note that the c++ compiler will insert the following if you don't provide one, default constructor, copy constructor, assignment operator, all of which may or may not work as intended depending on the underlying members, as such its always wise to implement our own, in this case your ok, ie you don't have any raw pointers, but something to keep in mind when runtime bugs start appearing and you have no idea why.

Upvotes: 1

Kirby
Kirby

Reputation: 3709

To grow or shrink the array as requested by the user, make a new array of the desired size, and copy the elements over one by one. This is an O(n) operation, but you don't have access to memory unless you explicitly declare it on the stack as you have, or by using new or malloc with a pointer.

In any case, you can just make a second array of the desired post-grow/post-shrink size. I would recommend using new/malloc so that you can move your pointer for the variable to the newly created array. Also, I would recommend cleaning up the memory from the array after it's been copied to the new one.

A different data structure might also by considered, such as a linked list.

Upvotes: 0

Related Questions