I have the following setup:
main.cpp:
int main()
{
vector <Tour> tourList;
Tour* tour_ptr;
for (unsigned int i = 0; i < tourList.size(); i++)
{
tour_ptr = &tourList[i];
tour_ptr->display();
}
}
Tour.h:
class Tour
{
public:
virtual void display();
};
Tour.cpp:
void Tour::display()
{
cout << "Tour ID: " << getID() << "\n";
cout << "Description: " << getdescription() << "\n";
cout << "Tour Fee: $" << getfee() << "\n";
cout << "Total Bookings: " << getbookings() << "\n\n";
}
GuidedTour.h:
class GuidedTour : public Tour
{
public:
void display();
};
GuidedTour.cpp:
void GuidedTour::display()
{
Tour::display();
cout << "Max Tour Group Size: " << getMaxTourists() << "\n";
cout << "Tour Guide: " << getGuideName() << "\n";
cout << "Tour Date: " << getTourDate() << "\n\n";
}
GuidedTour inherits from the Tour class, and I've specified the display() function as virtual in the base Tour class, but for some reason, the GuidedTour display() function never gets called, only the base function gets called every time. What am I doing wrong?
Your code actually doesn't print anything as the std::vector
would initially be empty. Other than that, your problem is caused by object slicing (I'm assuming that you are push_back()
ing GuidedTour
s into the vector).
When object slicing takes place, you are storing only the Tour
part of your GuidedTour
object(s), and that's the reason why you are seeing the output of Tour::display()
.
To solve your problem, you need to store the objects polymorphically, by using (smart) pointers and dynamically-allocating your objects.
int main()
{
vector <std::unique_ptr<Tour>> tourList;
for(...) {
tourList.push_back(std::make_unique<GuidedTour>(/* constructor parameters */));
...
tourList.push_back(std::make_unique<Tour>(/* constructor parameters */));
}
for (unsigned int i = 0; i < tourList.size(); i++)
{
tourList[i]->display();
}
}
Notice that I am using std::unique_ptr
/std::make_unique
and not raw new
ed pointers. Using them would greatly ease you of the problem of manually managing and delete
ing your objects, which sometimes[understatement] are the cause of bugs and undefined behavior.
Note that some people might suggest you to use boost::ptr_vector
or something similar. Listen to them, especially if they give you arguments on why they are better than the alternatives.
Your problem has nothing to do with your classes, rather how you are creating the object. Each element in the tourList vector is a tour, and nothing at compile time or runtime is there to determine that they are GuidedTours. In effect, GuidedTour is never called, because I don't see a GuidedTour object in your main anywhere.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With