Pete
Pete

Reputation: 784

How to access a variable in the derived class in c++?

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

enter image description here

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

Answers (2)

p.i.g.
p.i.g.

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

R Sahu
R Sahu

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

Related Questions