Grading system with templates

I'm currently working on a project in which I'm able to enter in the grades of each class as well as the student name(I'll work on that next). Things are looking off to an okay start, but I want to display the classes followed by the grade.Right now I made an array to go through the grades, but not the classes. I tried inserting words into a separate array containing the classes and didn't work. So I deleted some of the work but kept one line of code (line 26) and wondered why that is incorrect. It may be because with the template class present I've been trying to learn.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  #include<iostream>
#include<string>
using namespace std;

template <class T>
class grades
{
public:
	grades();
	void input(T);
	string getname() { return name; }
private:
	T* arr;
	T* arr2;
	string name;
	int size = 4;
	int top;
	
};

template <class T>
grades<T>::grades()
{
	arr = new T[size];
	top = -1;
	//arr2 = new T[size] = { "Math","Science" };//classes inside array here
}



template <class T>
void grades<T>::input(T grade)
{
	cout << "Enter in the grades for the following: " << endl;
	cout << "----------------------------------------" << endl;
	cout << "Math, English, History, Science" << endl;
	cout << "----------------------------------------" << endl;
	for (int i = 0; i < size; i++)
	{
		cin >> grade;
		arr[++top] = grade;
		
	}
	
	for (int i = 0; i < size; i++)
	{
		
		cout << arr[i] << " ";

	}
}

int main()
{
	char anwser;
	int grade = 0; 
	do {
		grades<int>enter;

		enter.input(grade);
		cout << "wish to keep going?(Y/N): ";
		cin >> anwser;
	} while (anwser == 'Y' || anwser == 'y');
}
Last edited on
first, the point of templates is to allow you to have different types of things. Containers are a classic example: if you made a tree template class, you might like to have a tree of integers, and another of strings.

//arr2 = new T[size] = { "Math","Science" };//classes inside array here

^^ that pretty much means that if you make your template anything but strings or things that can be reduced to strings, it will not work. It looks like there is no sense in a template here, what types do YOU expect to allow as type T in your class? If the answer is <string> or <my class that can polymorph to a string> then you may not need all this complexity of templates. If the answer is any of {int, double, string, my class} or something like that where you have multiple candidates, then you need the template but you will need to revisit what you are trying to do.

that said, I believe you have an extra = in there.

assuming T is a type that allows you to stick strings into it, then:

try
//arr2 = new T[size] { "Math","Science" };

^^ and, that really, really should be a vector<T>
(and if you tell me your professor does not allow vectors when you are writing templates, someone needs to be bonked in the head repeatedly with silly putty).
Last edited on
So I should use vector for that part then? Alright thanks for the input I'll have to go back and brush up a little on that then.
you almost never need new and delete. Treat them as a red flag of "stop and think again".
yea, you 'need' them sort of if you hand roll a tree or list container for school. And there are other rare places where it makes sense. But in general, every time you see one in your code, stop to ask yourself why you were unable to use an STL container there. If you can't answer that sensibly, rethink. Unfortunately, this is not said in school, or not said enough. In fact, they encourage pointers, due to trying to show you how stuff works at the low level and by teaching classical data structures that are pointer heavy.
Last edited on
This is a fairly complex task.

Sure, vectors make management of the lists easier but there is a more fundamental challenge here in that, as a suggestion, making a clear separation between the objects (types) you are modelling unravels some of the sweat.

You can pile everything into one class, as you have done, and have a variety of array/container types but there is a generic (templated) way which might make life simpler by separating individual grades and subjects from their respective lists.

Without any error checking, garbage collection/destructor(s), and limiting size to 4 (purely for convenience) here's what I mean:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include<iostream>
#include<string>

using namespace std;

template <class T>
class Listing
{
private:
    T* arr = nullptr;
    int size = 4;
    int top = 0;
    
public:
    Listing()
    {
        arr = new T[size];
        top = 0;
    }
    
    void addItem(T anItem)
    {
        arr[top] = anItem;
        top++;
    }
    
    T getItem(int anIndex)
    {
        return arr[anIndex];
    }
};

template <class U>
class Item
{
private:
    U item_name;
    
public:
    Item(){}
    void setName(U aItemName){ item_name = aItemName;}
    U getName(){return item_name;}
};

typedef Item<int> grade;
typedef Item<string> subject;

void input(Listing< grade >* aListing)
{
    int temp;
    grade gr;
    
    cout
    << " Enter in the grades for the following: \n"
    << "----------------------------------------\n"
    << "   Math, English, History, Science\n"
    << "----------------------------------------\n";
    
    for (int i = 0; i < 4; i++)
    {
        cin >> temp;
        gr.setName(temp);
        aListing->addItem(gr) ;
    }
}

int main()
{
    Listing<grade> list_of_grades;
    Listing<subject> list_of_subjects;
    
    input(&list_of_grades);
    
    for(int i = 0; i < 4; i++)
        cout << i << ". " << list_of_grades.getItem(i).getName() << '\n';
    
    return 0;
}


BTW:
1. You'll need another input function for adding to the subject Listing. i.e. int's for grades, strings for subjects.
2. You can list out the subjects in input() from the current subject Listing.
Thank you all for giving me some advice. I've decided to go with jonnin's advice first. If that doesn't work well, I'll do the two separate classes. Here's what I have at the moment:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include<iostream>
#include<string>
#include <vector>
using namespace std;

template <class T>
class grades
{
public:
	grades();
	void input(T, vector<string>v);
	void input2(T);
	//string getname() { return name; }
private:
	T* arr;
	int size = 4;
	int top;
	
};

template <class T>
grades<T>::grades()
{
	arr = new T[size];
	top = -1;
}

template <class T>
void grades<T>::input2(T name)
{
	cout << "Enter in your name: ";
	getline(cin, name);

}


template <class T>
void grades<T>::input(T grade, vector<string>v)
{
	v = { "Math","English","History","Science" };
	cout << "Enter in the grades for the following: " << endl;
	cout << "----------------------------------------" << endl;
	cout << "Math, English, History, Science" << endl;
	cout << "----------------------------------------" << endl;
	for (int i = 0; i < size; i++)
	{
		cin >> grade;
		arr[++top] = grade;
		cout << endl;
	}
	
	for (int i = 0; i < size; i++)
	{
		cout << v[i] << " :" << endl;
		for (int j = 0; j < size; j++)
		{
			cout << arr[j] << endl;
		}
	}

}

int main()
{
	char anwser;
	int grade = 0; 
	string name;
	vector<string>v;
	do {
		
		grades<int>enter;
		grades<string>enter2;
		enter2.input2(name);
		enter.input(grade,v);
		cout << "wish to keep going?(Y/N): ";
		cin >> anwser;
	} while (anwser == 'Y' || anwser == 'y');
}


I may need help with lines 52-59 with display. I'm almost there, but need some help here now. This is the output I currently get:

Math:
54
43
75
65
English:
54
43
75
65
History:
54
43
75
65
Science:
54
43
75
65

I know why it does this,but trying to think of an alternate way to do this without completely changing the code if possible.
Last edited on
Topic archived. No new replies allowed.