Reputation: 784
I have a vector of several different class data types and I'm trying to print the derived class variable.
Here is the diagram of the Classes
I have the diagram implemented. I am trying to print score from the assignment class in the grading class.
The error is in the friend ostream& operator<<(ostream& os, const CourseWork& dt) function.
Here is my classes
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <iomanip>
using namespace std;
/* -------------------------------------------------------- */
/* ---------------------- Grading Class ------------------- */
/* -------------------------------------------------------- */
class Grading
{
public:
string name;
int percent;
void get_raw_score();
void get_adj_score();
};
/* -------------------------------------------------------- */
/* ---------------------- Assignment Class ---------------- */
/* -------------------------------------------------------- */
class Assignment : public Grading
{
protected:
int score;
};
/* -------------------------------------------------------- */
/* ---------------------- Exam Class ---------------------- */
/* -------------------------------------------------------- */
class Exam : public Grading
{
protected:
int score;
Exam(string n, int g, int s) {
name = n;
percent = g;
score = s;
}
};
/* -------------------------------------------------------- */
/* ------------------- Project Class ---------------------- */
/* -------------------------------------------------------- */
class Project : public Assignment
{
public:
string letter_grade;
Project(string n, int g, string l_g) {
name = n;
percent = g;
letter_grade = l_g;
}
};
/* -------------------------------------------------------- */
/* ---------------------- Quiz Class ---------------------- */
/* -------------------------------------------------------- */
class Quiz : public Exam
{
public:
string letter_grade;
Quiz(string n, int g, string l_g) : Exam(n, g, score)
{
name = n;
percent = g;
letter_grade = l_g;
}
};
/* -------------------------------------------------------- */
/* ---------------------- CourseWork class ---------------- */
/* -------------------------------------------------------- */
class CourseWork {
public:
CourseWork() {}
void push_back(Quiz * a) {
work.push_back(a);
}
void push_back(Exam * a) {
work.push_back(a);
}
void push_back(Project * a) {
work.push_back(a);
}
// print the data and sort by name
void sort_name() {
for (int i = 0; i < (int)work.size(); i++)
cout<< work.at(i)->name <<endl;
}
void sort_score() {
}
friend ostream& operator<<(ostream& os, const CourseWork& dt) {
cout << "Grading" << std::setw(20) << "Percentage" << std::setw(20) << "Raw-Score" << endl;
for (int i = 0; i < (int)dt.work.size(); i++) {
// cout << dt.work.at(i)->name << std::setw(20) << dt.work.at(i)->percent << dt.work.at(i)->score <<endl;
os << dt.work.at(i)->name << std::setw(20) << dt.work.at(i)->percent << dt.work.at(i)->letter_grade;
}
return os;
}
private:
vector<Grading*> work;
};
/* -------------------------------------------------------- */
/* ---------------------- MAIN ---------------------------- */
/* -------------------------------------------------------- */
int main () {
CourseWork c;
c.push_back(new Quiz("Quiz", 5, "B-"));
c.push_back(new Quiz("Quiz", 5, "C+"));
c.push_back(new Quiz("Quiz", 5, "A"));
// c.push_back(new Exam("Midterm", 10, 50));
// c.push_back(new Exam("Final", 30, 85.5));
// c.push_back(new Project("Project", 5, "A-"));
// c.push_back(new Project("Project", 15, "B-"));
// c.push_back(new Project("Project", 15, "B-"));
// c.push_back(new Project("Demo", 10, "C"));
cout << "** Showing populated data..." << endl;
cout << c << endl << endl;;
// c.sort_name();
// c.sort_score();
return 0;
}
Upvotes: 0
Views: 137
Reputation: 2985
You are storing Grading*
objects in your CourseWork
object:
vector< Grading* > work;
So you cannot access the members of a derived class through the pointer of the base class. You should introduce a new (pure) virtual function in your base class which shall print the parameters of the derived class.
class Grading
{
public:
virtual ~Grading() {}
virtual print() const = 0;
// ...
}
And you shall implement this in all your derived class.
Also it makes no sense to create these functions if you add the given parameters into the same verctor:
void push_back( Quiz* a )
{
work.push_back(a);
}
void push_back( Exam* a )
{
work.push_back(a);
}
void push_back( Project* a )
{
work.push_back(a);
}
You just need one function:
void push_back( Grading* a )
{
work.push_back(a);
}
Or if you really want to access the members of the derived classes then you need to cast. But use the virtual methods instead.
Upvotes: 1
Reputation: 206577
One way to print the derived classes is to create a virtual
member function in the base class Grading
, create overriding member function is derived classes when necessary, and use the virtual
member function in the non-member function.
In Grading
:
virtual ostream& write(ostream& os) const
{
return os << this->name << std::setw(20) << this->percent;
}
In Project
:
virtual ostream& write(ostream& os) const
{
// Use the immediate base class to call the base
// class implementations first.
// Then write the data appropriate for this class.
return Assignment::write(os) << this->letter_grade;
}
Create a non-member function for operator<<
between std::ostream
and Grading
.
ostream& operator<<(ostream& os, const Grading& gr)
{
return gr.write(os);
}
Use above non-member function from the function that writes out CourseWork
.
friend ostream& operator<<(ostream& os, const CourseWork& dt) {
os << "Grading" << std::setw(20) << "Percentage" << std::setw(20) << "Raw-Score" << endl;
for (int i = 0; i < (int)dt.work.size(); i++) {
os << *(dt.work.at(i)) << std::endl;
}
return os;
}
Upvotes: 1