Please send questions to st10@humboldt.edu .

/*--------------------------------------------------------
 Implementation file for class Student WITH 
    explicitly-defined destructor, copy constructor, and 
    overloaded assignment operator.
 
 created by: Sharon Tuttle
 last modified: 12-3-03
---------------------------------------------------------*/
#include <iostream>
#include "Student2.h"
using namespace std;

//-----
// implementation of constructors
//-----

Student::Student (string gvn_lastName, string gvn_firstName,
         int gvn_numGrades)
{
    lastName = gvn_lastName;
    firstName = gvn_firstName;
    numGrades = gvn_numGrades;

    gradesArray = new double[numGrades];
}
        
Student::Student ()
{
    lastName = "";
    firstName = "";
    numGrades = 0;
    gradesArray = NULL;
}

//-----
// implementation of copy constructor
//-----

Student::Student (const Student& studentObject)
{
    lastName = studentObject.lastName;
    firstName = studentObject.firstName;
    numGrades = studentObject.numGrades;

    if (numGrades > 0)
    {
	gradesArray = new double[numGrades];

	for (int i=0; i < numGrades; i++)
	{
	    gradesArray[i] = studentObject.gradesArray[i];
	}
    }
    else
    {
	gradesArray = NULL;
    }    
}

//-----
// implementation of destructor
//-----

Student::~Student()
{
    delete [ ] gradesArray;
}

//-----
// implementation of accessor functions
//-----
string Student::get_lastName() const
{
    return lastName;
}

string Student::get_firstName() const
{
    return firstName;
}

int Student::get_numGrades() const
{
    return numGrades;
}

// returns the ith grade for this student
//    (return -1 if gradesArray NULL or
//    i is out-of-bounds)
double Student::get_grade(int i) const
{
    // make sure it is reasonable to even attempt to
    //    grab this grade... return -1 if it ISN'T
    if ((gradesArray == NULL) ||
        ((i < 0) || (i >= numGrades)))
    {
        return -1;
    }

    // IF reach here --- should be OK to at least
    //    TRY to grab ith grade.
    // (IF user hasn't set yet? well... OK, they're stuck
    //    then...)
    else
    {
        return gradesArray[i];
    }
}

//-----
// implementation of mutator functions
//-----
void Student::set_lastName(string new_lastName)
{
    lastName = new_lastName;
}

void Student::set_firstName(string new_firstName)
{
    firstName = new_firstName;
}

// note that this also dynamically allocates
//    a gradesArray of this size...
void Student::set_numGrades(int new_numGrades)
{
    numGrades = new_numGrades;

    // draconian as specified: if were grades before,
    //    they are now NUKED...
    if (gradesArray != NULL)
    {
        delete [ ] gradesArray;
    }

    // in ALL cases: allocate a new gradesArray of this
    //    new size
    gradesArray = new double[numGrades];
}

// set the ith grade in gradesArray to newGrade
void Student::set_grade(int i, double newGrade)
{
    if ((i < 0) || (i >= numGrades))
    {
        cout << "Student::set_grade: index " << i 
             << " is out of bounds!" << endl;
    }
    else
    {
        gradesArray[i] = newGrade;
    }
}

//-----
// implementation of overloaded operators
//-----
void Student::operator =(const Student& rightHandStudent)
{
    lastName = rightHandStudent.lastName;
    firstName = rightHandStudent.firstName;
    numGrades = rightHandStudent.numGrades;

    if (numGrades > 0)
    {
	gradesArray = new double[numGrades];

	for (int i=0; i < numGrades; i++)
	{
	    gradesArray[i] = rightHandStudent.gradesArray[i];
	}
    }
    else
    {
	gradesArray = NULL;
    }    
}   

//-----
// implementation of other member functions
//-----

//----
// Contract: avgGrade : void -> double
// Purpose: returns the average of the grades
//          in calling Student's gradesArray;
//          returns -1 if gradesArray == NULL.
//
// Examples: for Student emptyStudent(); :
//              emptyStudent.avgGrade() == -1
//           for Student exStudent("Geo", "Jon", 3);
//              with grades 100, 80, 75,
//              exStudent.avgGrade() == 85
//----- 
double Student::avgGrade() const
{
    double sumGrades = 0;

    if (numGrades == 0)
    {
        return -1;
    }
    else
    {
        for (int i=0; i < numGrades; i++)
        {
            sumGrades += gradesArray[i];
        }
        
        // KNOW numGrades != 0...
        return sumGrades / numGrades;
    }
}

//-----
// Contract: hasHigherAvgThan : Student -> bool
// Purpose: returns true if calling Student has
//          an average grade higher than 
//          otherStudent; returns false otherwise.
//
// Examples: if Student student1("A", "A", 3)
//              has grades 100, 80, 75,
//           Student student2("B", "B", 4)
//              has grades 80, 80, 90, 90, and
//           Student student3("C", "C", 3)
//              has grades 86, 87, 88,
//           then:
//   student1.hasHigherAvgThan(student2) == false
//   student3.hasHigherAvgThan(student2) == true
//   student1.hasHigherAvgThan(student3) == false
//-----
bool Student::hasHigherAvgThan(Student otherStudent) const
{
    return (avgGrade() > otherStudent.avgGrade());
}