1

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
    ~GraduateStudent(); //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.

Nick
  • 9,285
  • 33
  • 104
  • 147
  • 2
    why private inheritance? and `year` has to be virtual in the base class, otherwise you cannot _override_ it – Vlad Oct 11 '11 at 15:43
  • [`using namespace std;`](http://stackoverflow.com/questions/2879555/c-stl-how-to-write-wrappers-for-cout-cerr-cin-and-endl/2880136#2880136) – sbi Oct 11 '11 at 15:45
  • I used private inheritance because I was using an example's structure that was in the book. So, I just applied it to this problem. There was no method behind it. – Nick Oct 11 '11 at 15:46
  • @Nick: http://stackoverflow.com/questions/1576978/private-inheritance/1577007#1577007 – sbi Oct 11 '11 at 15:47
  • @sbi thanks for the link, that clears up what the book fails to really explain in any depth. People from stack should write text books, haha. It would make learning code much easier. – Nick Oct 11 '11 at 15:54
  • 1
    @Nick: There are good C++ books out there, although it's onyl preciously few: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – sbi Oct 11 '11 at 15:56
  • Well, You never know Nick, some people from SO like @sbi, probably already have written books, just they wont let you know because they are modest. :) – Alok Save Oct 11 '11 at 16:14
  • @Als: I have most definitely never written any books. [Others](http://stackoverflow.com/users/109934/), [however](http://stackoverflow.com/users/88656/), [have](http://stackoverflow.com/users/902497/) [indeed](http://stackoverflow.com/users/348571/). – sbi Oct 11 '11 at 17:07

5 Answers5

4

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.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
4

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.

Chad
  • 18,706
  • 4
  • 46
  • 63
  • Thanks! For the year() function, I was trying to put the if statements in the header file which resulted in errors. The HW problem doesn't ask for the .cpp file so it made me think that the statement needed to be in the header file. – Nick Oct 11 '11 at 15:58
  • 4
    When a question is tagged as "homework" it is usually better to provide hints as to what to look for, where the problem might be than providing full blown solutions that can be just copied and pasted – David Rodríguez - dribeas Oct 11 '11 at 15:59
  • @DavidRodríguez-dribeas: I strongly second that. – Alok Save Oct 11 '11 at 16:00
  • Wouldn't it be nice for StackOverflow to have some feature that tries to detect homework problems and auto-tags questions as such. – Michael Price Oct 11 '11 at 16:12
  • Yeah, but since the `Student` class that was "given" was apparently incorrect, and given the amount of work already shown by the OP, I felt this didn't really go to far in giving the answer. In fact, the actual work of creating the derived class was already done (in a mostly correct manner), and the implementation of the overridden `year()` function is still left as an exercise. I hate when teachers leave subtle bugs in "given" code, as most of the time it is out of a lack of understanding of the language by the teacher. – Chad Oct 11 '11 at 16:52
  • @Nick: you shouldn't have errors putting `if` statements in a header _if_ they are in a function. Show us what you tried. – Mooing Duck Oct 11 '11 at 18:10
3

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
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • Thank you for the suggestions. I will be conscious of these things moving forward. – Nick Oct 11 '11 at 16:02
  • @Nick I think the "probably" qualifiers in Davids answer are unnecessarily defensive. IMO you can disregard those. In a private inheritance relationship the virtual declaration of year() makes no sense, as the inheritance is hidden; And as other have pointed out, you need to make it virtual. Almost all statements using the terms "derived class" are assuming a public inheritance. – Captain Giraffe Oct 11 '11 at 16:18
0

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.

NoodleAwa
  • 93
  • 5
0

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.

DanS
  • 1,677
  • 20
  • 30