简体   繁体   中英

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

在此处输入图片说明

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;
}

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.

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM