开发者

Derived class in C++

I have a homework problem that asks:

Desgin a derived class GraduateStudent from base class Student. It adds a data member named Advisor to store the name of student’s thesis advisor. Provide constructor, destructor, accessor, and modifier functions. This class overrides the year function to returns one of two strings (“Masters” or “PhD”) depending on the number of hours completed, using using the chart below.

Hours Year

<=30 Masters

(greater than) 30 PhD

I've written:

using namespace std;


class Student
{
public:
    Student( string s = "", int h = 0);
    ~Student();
    string getName() const;
    int getHours() const;
    void setName(string s);
    void setHours (int h);
    string year () const;
private:
    string name;
    int hours;

};

class GraduateStudent: private Student
{
public:
    GraduateStudent(string s = "", int h=0, string advisor=""); //constructor
    ~GraduateStude开发者_开发知识库nt(); //destructor
    string getAdvisor();
    void setAdvisor(string advisor);
    //Class overrides??

private:
    string Advisor;
}

The class student was given, I've added the Graduate Student derived class.

My question is first if I have set up the derived class properly. My second question is how can I override the year function without if statements? I tried to use those statements but the editor gave me errors, I suspect since its a header file.


The student class you were "given" is not really written correctly to properly allow for overriding of the year function. A general use case scenario (where you hold student objects in a container won't work properly).

So, to fix (properly):

// Generally, poor practice to have a using namespace
// directive in a header file, instead just properly 
// scope your variables (as below)
// using namespace std;

class Student
{
public:
    Student( std::string s = "", int h = 0);

    // Virtual desctructors allow you to properly free derived
    // classes given a base class pointer
    virtual ~Student();

    std::string getName() const;
    int getHours() const;
    void setName(std::string s);
    void setHours (int h);

    // This function needs to be virtual to be overridable
    virtual std::string year () const;
private:
    std::string name;
    int hours;

};

// Use Public inheritance, after all a
// GraduateStudent IS-A Student
class GraduateStudent: public Student
{
public:
    GraduateStudent(std::string s = "", int h=0, string advisor=""); //constructor
    ~GraduateStudent(); //destructor
    std::string getAdvisor();
    void setAdvisor(string advisor);
    //Class overrides??

    // this function overrides the Student::year() function
    std::string year() const;

private:
    std::string Advisor;
}

Also, why do you think you are required to implement the year() function without using if statements? That would be the appropriate thing to do in this case.


If you declare a function with same name in derived class it hides all the functions with the same name in the base class.

So just adding:

string year () const;

To your derived class again would hide your Base class function.

Note that this is function hiding not overriding. For overriding you need the function to be declared as virtual in your Base class. And that is what the Q asks for:

Your base class should have:

virtual string year () const;

You further declare it in your derived class and then define it appropriately for the same.


Private Inheritance is not a good idea here because,
With Private Inheritance all the members of the Base class become private members of the derived class.

The above rule would mean you cannot call(on object of Derived class) any of the methods that have implementation only in Base class and none in Derived class, this is not what you are trying to implement is my guess.


To override a member function you only need to provide a declaration and definition in the derived type provided that the function is virtual. You cannot override a function in the base class if it is not virtual.

Because the point of the exercise is probably using a GraduateStudent as any other student, you probably want to use public inheritance. Private inheritance is usually employed only to provide a implemented in terms of rather than is-a relationship.

Other comments that come to mind on the implementations of the classes:

  • Constructors should be explicit, you probably don't want implicit conversions from strings
  • Student destructor should be virtual (or protected) to avoid undefined behavior if you try to delete a GraduateStudent through a pointer to Student
  • Strings in the setters are probably best passed by constant reference --there could be some discussion here, but beyond the scope of your course (i.e. with the new move-semantics, depending on the usage pattern either option might be better/worse.
  • Strings should be returned in accessors by const reference (undoubtely in this case)
  • Operations that do not modify the state of the objects should be marked const


The private inheritance from Student is limiting what access you have to its functions. In this case Public or Protected would be more use.

Declaring the year method as a virtual would allow you to implement it in the GraduateStudent class and have it called if your accessing the class as a Student.


Make the function virtual in the Student base class virtual string year(). Then provide a new definition in GraduateStudent that replaces the year method with what you want.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜