Achintha Gunasekara
Achintha Gunasekara

Reputation: 1165

Overload operator in subclass

tour and guided tour. Guided tour extends the tour class. I'm overloading << and >> operators in the tour class.

My tour class looks like

#include <iostream>
#include <vector>
#include "Customer.h"

using namespace std;

class Tour {

protected:
    string id;
    string description;
    double fee;
    vector<string> customerList;

public:
    Tour();
    Tour(string idVal, string descriptionVal, double feeVal);
    string getId();
    string getDescription();
    double getFee();
    double getTotalForTour();
    virtual void addCustomer(string cust);
    vector<string> getCustomers();
    virtual void display();

    friend ostream& operator<< (ostream &out, Tour &cust);
    friend istream& operator>> (istream &in, Tour &cust);
};

then my guided tour looks like this,

#include <iostream>
#include "Tour.h"
#include "SimpleDate.h"

using namespace std;

class GuidedTour : public Tour {

private:
    SimpleDate* date;
    string guideName;
    int maxNumTourists;

public:
    GuidedTour();
    GuidedTour(string idVal, string descriptionVal, double feeVal, SimpleDate* dateVal, string guideNameVal, int maxNumTouristsVal);
    virtual void addCustomer(string cust);
    SimpleDate* getDate();
    void display();

    friend ostream& operator<< (ostream &out, GuidedTour &cust);
    friend istream& operator>> (istream &in, GuidedTour &cust);
};

I want to overload these operators differently on the subclass to do something else.

I have a Vector that contains tours and guided tours.

When i loop through the vector and do following,

for (unsigned int i = 0; i < tourListVector.size(); i++) {

    cout << *tourListVector[i];
}

It always does what's specified in tour regardless even if the object is a guided tour.

Can you please help?

Upvotes: 1

Views: 4492

Answers (2)

Tristan Brindle
Tristan Brindle

Reputation: 16864

You're almost doing the right thing, but not quite. Let's take the output case first -- the input case works just the same.

First, you should declare a

virtual void write(std::ostream&) const;

member function in your base class. The implementation might be something like:

void Tour::write(std::ostream& os) const
{
    os << "ID: " << id << std::endl;
    os << "Description: " << description << std::endl;
    // etc
}

which I assume is the sort of code you have currently in your operator<<(ostream&, Tour&). Then you need to overload this in your derived class -- perhaps with something like

void GuidedTour::write(std::ostream& os) const
{
    Tour::write(os); // Write out base Tour info first
    os << "Guide Name: " << guideName << std::endl;
    // etc
}

After that, you can declare a free (i.e. non-member) operator<< overload for Tours, which calls your write() member function, like

std::ostream& operator<<(std::ostream& os, const Tour& tour)
{
    tour.write(os);
    return os;
}

for example.

Explanation: Forget the fact that your current operator<< is a friend; it has no bearing in this case. Instead, imagine you have two overloaded non-member functions called

void do_something(Tour& t); // (a)
void do_something(GuidedTour& gt); // (b)

Since your tourListVector contains (I assume) Tour* pointers, if you were to loop through the vector and call do_something() on each element, the compiler would only be able to match function (a) above. That's because it has no way of knowing that some of the Tour* pointers might, for a given run of your programme, actually point to GuidedTour instances. In order to do run-time dispatching like this, you need to use virtual functions.

Aside: (I know this is example code, but if you're new to C++ then it's worth pointing out just in case you weren't aware :-) )

Because you're using Tour* pointers, you should define a virtual destructor for your base class. If you don't, the compiler won't know that it might need to destruct all the members of the GuidedTour class when you call delete on a Tour*. In fact, it's generally good practice to make your destructor virtual if your class includes any other virtual functions, just to save potential problems later.

Also, please don't put using namespace std; in a header file :-)

Upvotes: 3

Sukhanov Niсkolay
Sukhanov Niсkolay

Reputation: 1328

If i understood right, you have pointers in your vector. So you should use key word virtual. And read about virtual methods in C++.

Upvotes: 0

Related Questions