1

So I happened to finish my homework program but today during lecture my good ol professor told us we are not allowed to use STL as in vectors or list to create our database. We were also told we need all our variables private. I was doing this program completely wrong. This is what I have so far.

in class.h

class Student {
   private:
    string last;
    string first;
    int student_id;
    int enroll_id;
    int *grades;
}

class Gradebook {
   public:
    Gradebook();
    void newCourse(Gradebook *info);
   private:
    string name;
    int course_id;
    int count_course;
    int enroll;
    Student *students;
   public:
    //Constructor
}

I know I can access private members of Gradebook by using a constructor so I can set every member in my Gradebook.

function to create a newCourse

Gradebook::Gradebook() {

  students = new Student;
  course_id=0;
  count_course=0;
  enroll = 0;
}

Gradebook::newCourse(Gradebook *info) {

  int i, loop=0;

  cout << "Enter Number of Courses: ";
  cin >> loop;

  info = new Gradebook[loop];

  for(i=0; i<loop; i++) {

    cout << "Enter Course ID: ";
    cin >> info[info->count_course].course_id;

    cout << "Enter Course Name: ";
    cin >> info[info->count_course].name;

    info->count_course++

  }
}

So Courses are now sets. Since the variables in Student are private. I can't just use a pointer to the variables to access them. Can someone show me how to do this?

Mykola
  • 3,343
  • 6
  • 23
  • 39
user2816227
  • 173
  • 2
  • 13
  • What is the behavior of a Student object? – Ben Voigt Apr 24 '14 at 19:20
  • 2
    If the teacher said to make the member variables private, hopefully they also told you about using accessors (a public function that can get or set the value in a private member variable). While popular in Java and C#, this is not as widely used in C++. – crashmstr Apr 24 '14 at 19:21
  • Also, you should be using `i` more in your loop. – crashmstr Apr 24 '14 at 19:23
  • @BenVoigt still new to C++ so I don't know how to answer that question . – user2816227 Apr 24 '14 at 19:38
  • The first cout within newCourse makes no sense. Why is a course id the size of the array? Perhaps that is a copy and paste error. also your student array only points to a single student. Is that really what you wanted? – shawn1874 Apr 24 '14 at 19:43
  • @shawn1874 Thats my question how do i build my student class? Any help is appreciated. – user2816227 Apr 24 '14 at 19:47
  • @shawn1874 your right it is a typo it is fixed now. – user2816227 Apr 24 '14 at 19:48
  • Similarly to how you build your gradebook class. You need to use a variable or constant within [] to specify how many elements to make. Personally I would just use a constant for your arrays unless your requirement is to have dynamic arrays. Your instructor is making it more difficult by telling you not to use the STL. – shawn1874 Apr 24 '14 at 19:49
  • http://www.cplusplus.com/doc/tutorial/dynamic/ this isn't a particularly easy assignment but you'll need to study links like that one to figure out how to create and manage dynamic arrays or simply build arrays of constant size with a number like 50 or 100. – shawn1874 Apr 24 '14 at 19:51
  • @shawn1874 My first build was a const database having x_amount of courses, x_amount of students, where everything had a limiter. Now I have to do it dynamically without using STL. Its so confusing! – user2816227 Apr 24 '14 at 19:55
  • @crashmstr: Accessors are an anti-pattern. Functions should be added to give the class *behavior*, not just publish private variables. – Ben Voigt Apr 24 '14 at 21:08
  • @user2816227 - `my good ol professor told us we are not allowed to use STL as in vectors or list to create our database` Hey, of course not. And now you've learned how to make a buggy program that I can break with a three line main() program. Seriously, you're supposed to be learning how to make bug-free programs, not buggy ones. Why these type of assignments still exist is beyond me... – PaulMcKenzie Apr 24 '14 at 21:26

4 Answers4

0
class Student {
   private:
    string last;
    string first;
    int student_id;
    int enroll_id;
    int *grades;
  public:
    string &getLast(){ return Last; }
    ...
    ...
};

Call Student::getLast() when you need to access your last variable etc

or
void setLast(string sLast){last = sLast;} for writing and
string getLast(){return last;} for reading

And example of dynamic array:

    struct Student;
int Count = 0;
Student *Students = nullptr;

int AddStudent(Student nStudent)
{
    Student *Buffer = new Student[Count + 1];
    for (int a = 0; a < Count; a++)
        Buffer[a] = Student[a];
    Buffer[Count] = nStudent;
    if(Students)
        delete[] Students;
    Students = Buffer;
    return ++Count -1
}
void RemoveStudent(int Index)
{
    Student *Buffer = new Student[Count - 1];
    for (int a = 0; a < Index; a++)
        Buffer[a] = Students[a];
    for (int a = Index; Index < Count - 1; a++)
        Buffer[a] = Students[a - 1];
    if (Students)
        delete[] Students;
    Students = Buffer;
}
Quest
  • 2,764
  • 1
  • 22
  • 44
  • Could you give me an example on how that works? And how does the Student class expand when more students are added using an accessor. Using a set function will only make last = last overriding the previous data. – user2816227 Apr 24 '14 at 19:36
  • It doesn't. More students cannot be added using an accessor. The accessor only works on the student object that you are accessing. You really have a lot of studying to do in order to figure this out. Your questions are too vague. It appears that you are going to have to find some articles on dynamic arrays using new and delete. This is easy to do using a google search. – shawn1874 Apr 24 '14 at 19:47
  • @shawn1874 everything i've googled doesn't apply to dynamically allocated classes. My design is info[number of courses].students[number of students].variables, its going to be a class with pointers to pointers to variables. I've googled everything I couldn't think of but I am not getting the required results Im asking for maybe due to lack of knowledge. – user2816227 Apr 24 '14 at 19:53
  • This allows `studentPtr->getLast() = "lastname";`, did you really want that? – Ben Voigt Apr 24 '14 at 21:11
  • @Ben Yes i did. I don't know if this is what he wants. – Quest Apr 25 '14 at 07:13
0

Ok I didnt know how to ask this question but I actually answered it. But I want everyones opinion on my method.

class Student {
  public: 
   void setID(int ID){student_id = ID; };
   int getID(){return student_id);
  private:
   string last;
   string first;
   int student_id;
   int enroll_id;
   int *grades;
};

class Gradebook {
 public:
  Gradebook();
  void newCourse(Gradebook *info);
  void newStudent(Gradebook *info);
private:
  string name;
  int course_id;
  int count_course;
  int count_student;
  int enroll;
  Student *students;
public:
//Constructor
}

void Gradebook::newStudent() {

    int i, loop=0;

int student=0;
string lastName;

cout << "Enter number of students: ";
cin >> loop;

for(i=0; i<loop; i++) {

    cout << "Enter Student ID: ";
    cin >> student;

    info->students[info->count_student].setID(student);

    cout << "Enter Last Name: ";
    cin >> lastName;

    info->students[info->count_student].setLast(lastName);

    info->count_student++;

}
}

Is there anything wrong of doing it this way?

user2816227
  • 173
  • 2
  • 13
  • 1
    This will probably work for your homework, but in the long run you should learn about constructors, and set your variables that way. – Ben Voigt Apr 24 '14 at 21:10
  • Are you allowed to use `unique_ptr` ? That will still let you manage allocation and copying yourself, but does the `delete[]` automatically for you, and also makes sure that you don't get copying and assignment operators that do the wrong thing. Did you learn about the "Rule of Three"? – Ben Voigt Apr 24 '14 at 21:14
0

edit: You can't use 'Student *students' for your container for multiple Students...

You could use your own lists. Something like

struct Participant{ // or class (and maybe more clever name)
    Student *student;
    Participant *prev;
    Participant *next;
};

You have to do little pointer-acrobatics, but maybe that's the idea for this exercise.. And like in previous answer, use get and set functions in your Student class.

Tony
  • 31
  • 3
  • I have to sue a class instead of a struct, using a struct was 2 assingments ago. – user2816227 Apr 24 '14 at 21:07
  • @user2816227 - I'll ask you -- do you know the difference between a class and a struct? The reason why I ask is because what you just stated made very little sense. – PaulMcKenzie Apr 24 '14 at 21:23
0

Ok, I'm sorry but your code is a mess... I can't do this homework for you, but here is few tips that came in mind

  1. Are you sure that it wouldn't be easier to make different classes for Student, Course and Gradebook? I don't know your homework specifications, so I can't be sure what it is that your program should actually do.

  2. You can not use int *grades to store all of one students grades. Same goes for Student *students. You can not access iterate *students like an array students[i].something() If you use some help class(or struct) like Participant, you have to find right student by iterating in loop. Notice, that you have store 'first' participant inside your class and 'int students' keep in your student count (also inside your class)

    Participant *current = first;
    int id = Id; // Id is from function/method call
    
    for(unsigned int i = 0; i < students; ++i){
       if(current->getId()== id){
           // do something and
           break;
       }
       else if(current->next != NULL){ // test this just in case
           current = current->next;
       }
       else break; // something went wrong
    }
    

It might be good idea to store all students in one list (that you make) and use pointers in Course or in Gradebook or where ever... If you know 'static' here is a hint

    class Student{
        public:
           .   // get and set functions
          static Student* getStudent(int id); // return NULL if no student with id
        private:
          static Student *first;
          static Student *last;
          static unsigned int counter; // helps with loops, but you can always use next != NULL
          Student *next;
          Student *prev;
    }

Put this inside the Student constructor with first student that you create you set first and last to point him/her, and next and prev to NULL. After that, always when you create a new student you set

    this->prev = last;
    last->next = this;
    last = this;
    this->next = NULL;
  1. Do not implement program logic inside class. Do it in main() or in some other function, but i think main() is fine for now. If you need to add new student in gradebook, ask all the necessary info in main() and make some function like Gradebook::newStudent(int &Id, string &last_name){ // store student info in gradebook }

Usually these homework programming exercises don't have be too fancy or streamlined or fully optimized. So don't overdo them ;)

Tony
  • 31
  • 3