Subhranil Dey
Subhranil Dey

Reputation: 25

implementation of a C++ function of a class that uses other classes

typedef Map<int, char> StudentMap;

class SchoolManagementSystem
{
private:
    SmarterArray<Student> studentList; //A SmarterArray to store the students in the school
    SmarterArray<Course> courseList; //A SmarterArray to store the courses in the school
    SmarterArray<StudentMap> studentMapList; //A SmarterArray to store the students' maps

public:
    //Constructors
    SchoolManagementSystem();

    //Getters
    int getNumberOfRegisteredStudents() const;
    int getNumberOfCoursesOffered() const;
    int findStudent(const string &firstName, const string &lastName) const;
    Student getStudent(const int &studentIndex) const;
    StudentMap getStudentMap(const int &studentIndex) const;
    int findCourse(const string &courseName) const;
    Course getCourse(const int &courseIndex) const;
    double getStudentGPA(const int &studentIndex) const;
    int getTopStudentIndex() const;

    //Setters
    bool registerStudent(const Student &s);
    bool enrolStudent(const int &studentIndex, const int &courseIndex);
    bool assignLetterGrade(const int &studentIndex, const int &courseIndex, const char &letterGrade);
    bool offerCourse(const Course &course);
    void removeStudent(const int &studentIndex);
    bool withdrawStudent(const int &studentIndex, const int &courseIndex);
    void removeCourse(const int &courseIndex);

    //Static functions
    static Student generateRandomStudent();
    static char generateRandomLetterGrade();

    //Friend functions
    friend ostream& operator << (ostream &, const SchoolManagementSystem &);
};



    bool SchoolManagementSystem :: enrolStudent(const int &studentIndex, const int &courseIndex)
{
    assert((studentIndex < this->studentList.getSize() || studentIndex >= 0) && (courseIndex < this->courseList.getSize() || courseIndex >= 0));

    if(this->getStudentMap(studentIndex).findKey(courseIndex) != -1)
        return false;
    else
    {
//        StudentMap S;
//        S.append(courseIndex, 'N');
//
//        this->studentMapList.append(S);

        this->getStudentMap(studentIndex).append(courseIndex, 'N');
        //this->studentMapList[studentIndex].append(courseIndex, 'N');
//        this->getStudentMap(studentIndex).A1.append(courseIndex);
//        this->getStudentMap(studentIndex).A2.

        return true;
    }
}

The function definition given below is supposed to add an element in the map class array within the studentMapList array in The SchoolMaganementSystem class. The definition of the function does not do it, I assure you that the appent in SmarterArray, StudentMap works fine when tested individually.

Upvotes: 0

Views: 164

Answers (1)

ShadowRanger
ShadowRanger

Reputation: 155333

All of your get* methods are returning by value, not by reference, so you get a personal copy that is unrelated to the version stored in the SchoolManagementSystem instance. You can change them, but since they're not related to the copy held in the SchoolManagementSystem instance, those changes aren't seen anywhere else.

If you need to be able to view the values and mutate them, you should change your current interface of:

StudentMap getStudentMap(const int &studentIndex) const;

to a paired interface of:

StudentMap& getStudentMap(int studentIndex);
const StudentMap& getStudentMap(int studentIndex) const;

one of which can be used to get a mutable reference to the StudentMap on mutable SchoolManagementSystem instances, the other of which provides you an immutable view of the StudentMap on constant SchoolManagementSystem instances.

Side-note: There is zero benefit to accepting ints as const references (in practice, it usually means passing a 32-64 bit pointer that must be dereferenced to memory rather than just passing the raw [typically] 32 bit int itself); just take them by value (I changed the prototypes to behave that way).

All that said, 463035818_is_not_a_number is correct when they say that the non-constant version of the method is kind of a misuse of accessors; hiding the implementation but then effectively providing full access to it through an accessor (that allows users to violate whatever design constraints it is supposed to be under) gains very little. As they suggest, provide APIs on the class that allow for specific, allowed mutations (with input checks, constraint validation, what have you) instead of leaving it to users to write functions that mutate it from the outside in arbitrary ways.

Upvotes: 1

Related Questions