Example 2 - Review of classes, constructors and destructors

// File: day2ex2.cpp - Review example 2
#pragma warning(disable : 4996)	// Disable MS warning: 'strcpy': This function or variable may be unsafe ...

#include <iostream>
#include <cstring>
#include <cctype>
using namespace std;

class Name
{
public:
	Name(const char* name);
	Name(const Name&);
	~Name();
	const char* get_name() const { return name_ ? name_ : ""; }
private:
	char* name_;
};

Name::Name(const char* name = 0)
: name_(name ? new char[strlen(name)+1] : 0)
{
	if (name) strcpy(name_,name);
}

Name::Name(const Name& other)
: name_(new char[strlen(other.name_)+1])
{
	strcpy(name_,other.name_);
}

Name::~Name()
{
	if (name_) {
		delete[] name_;
		name_ = 0;
	}
}

const unsigned short noAssignments = 8;

class Student
{
	static const unsigned short MaxTotalPoints;

	Name name_;
	unsigned int id_;
	unsigned short assGrade_[noAssignments];
	unsigned short labExTotal_;
	unsigned short midterm_;
	unsigned short final_;
	unsigned short minOfFirst7Ass() const;
public:
	Student(const char*, unsigned int,
		unsigned short, unsigned short, unsigned short, unsigned short,
		unsigned short, unsigned short, unsigned short, unsigned short,
		unsigned short, unsigned short, unsigned short);
	unsigned short totalPoints() const;
	const char* grade() const;
};

const unsigned short Student::MaxTotalPoints = 350;

Student::Student(const char* name, unsigned int id,
				 unsigned short a1, unsigned short a2, unsigned short a3, unsigned short a4,
				 unsigned short a5 , unsigned short a6, unsigned short a7, unsigned short a8,
				 unsigned short labextotal, unsigned short midterm, unsigned short final)
				 : name_(name), id_(id), labExTotal_(labextotal), midterm_(midterm),final_(final)
{
	assGrade_[0] = a1;
	assGrade_[1] = a2;
	assGrade_[2] = a3;
	assGrade_[3] = a4;
	assGrade_[4] = a5;
	assGrade_[5] = a6;
	assGrade_[6] = a7;
	assGrade_[7] = a8;
}


unsigned short Student::minOfFirst7Ass() const
{
	unsigned short minAssGrade = assGrade_[0];
	for (unsigned i = 1; i < noAssignments-1; i++) {
		if (minAssGrade < assGrade_[i])
			minAssGrade = assGrade_[i];
	}
	return minAssGrade;
}

unsigned short Student::totalPoints() const
{
	unsigned short sum = 0;

	for (unsigned i = 1; i < noAssignments; i++) {
		sum += assGrade_[i];
	}
	sum -= minOfFirst7Ass();
	sum += labExTotal_ + midterm_ + final_;
	return sum;
}

const char* Student::grade() const
{
	static char Grade[3];
	memset(Grade,0,3);
	unsigned pct = static_cast<unsigned>(100.f * totalPoints()/MaxTotalPoints);
	if (pct > 98) {
		strcpy(Grade,"A+");
		return Grade;
	}
	Grade[0] = pct > 59 && pct < 100 ? "DCBA"[pct/10-6] : 'F';
	Grade[1] = (pct % 10 == 9) ? '+' : ((pct % 10 == 0) ? '-': ' ');
	return Grade;
}


int main()
{
	Student Joe("Joe Bentley",12345678,20,17,9,19,17,12,10,16,55,47,72);
	cout << Joe.totalPoints() << Joe.grade() << endl;
}

Review Questions

  1. What is the #pragma warning(disable : 4996) ?
  2. How does the Student - Name container relationship work?
  3. The Student class does not have a destructor - is there a memory leak here?
  4. Why is MaxTotalPoints defined as static const unsigned short and within the Student class?
  5. Why isn't noAssignments defined as part of the Student class?
  6. Why is Student::minOfFirst7Ass() private?
  7. Why is this line where it is -
    const unsigned short Student::MaxTotalPoints = 350; ?
  8. How does the Student::grade() function work?
  9. What is static_cast<unsigned> ?
  10. Should the four (11) unsigned short data members of the Student class be combined into one 11 element array of unsigned short?