1

I've followed the instructions I got from my last post and re-wrote my code.

My header file

#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <typeinfo>
#include "Tour.h"
#include "GuidedTour.h"

using namespace std;
class TourManager {

private:
    vector<Tour *> tours;
    void setupTour();
    string getUserInput();
    string displayMainMenu();
    void displayTourDetails();
    void callDisplayOnEach();
    void addBookingsToTour();

public:
    TourManager();
    void go();
};

Then I have a function to populate the "list" vector with tour and guidedTour objects.

void TourManager::setupTour() {

    tours.push_back(new Tour("FP001", "Fun Park 3 Day Pass", 110.00));
    tours.push_back(new GuidedTour("SK003", "Learn to Ski Adventure Tour", 240.00, "28/07
}

void TourManager::callDisplayOnEach() {

    for (vector<Tour *>::iterator it = tours.begin() ; it != tours.end(); ++it) 
    {
        if(typeid(*it) == typeid(GuidedTour)) 
        {    
            cout << "Guided Tour" << "\n";
        }
        else 
        {
            cout << "NOT Guided Tour : " << typeid(*it).name() << "\n";
        }
    }
}

However I always seems to be getting back Tour objects. EG: it always prints NOT Guided Tour.

how do I archive polymorphic behavior?

Can you please advice? (I'm new to C++) My required to use C++98

Many thanks

Achintha Gunasekara
  • 1,165
  • 1
  • 15
  • 29
  • 1
    This is because of vector type. Keep seperate vector list for adding guidedtour objects. – user1502952 Aug 30 '13 at 09:53
  • Yes, you have a list of pointers to Tour objects...hence referencing the list will always yield a Tour*. Shouldn't be pushing GuidedTour* on there - compiler will try to cast them to Tour* and that means trouble later on. – HvS Aug 30 '13 at 09:58
  • It's for a school assignment, I'm required to use a single vector and retrieve values from it – Achintha Gunasekara Aug 30 '13 at 09:59
  • how do I archive polymorphic behavior? thanks – Achintha Gunasekara Aug 30 '13 at 10:01
  • @HvS: Sure, the compiler will convert the _pointer_. It will not convert what the pointer points _to_. That is and remains a `GuidedTour` object. – MSalters Aug 30 '13 at 13:20

1 Answers1

5

This is not how polymorphism works.

How to achieve what you are trying to do

dynamic_cast<T> uses RTTI to check whether a polymorphic type is actually of type T:

GuidedTour * ptr = dynamic_cast<GuidedTour *>(*it);
if(ptr != NULL)
{
    std::cout << "This is a guided tour" << '\n';
}

However, RTTI comes at a cost; those are checks performed at runtime and will slow down your performance, and RTTI may not be supported at all.

What you usually should do

Avoid needing to know the exact type of your polymorphic object. Provide an interface that works well regardless and rely on calling your virtual methods to do the job.

class Tour
{
    public:
        virtual ~Tour() {}

        virtual void info() const
        {
            std::cout << "This is not a guided tour" << '\n';
        }
};

class GuidedTour : public Tour
{
    public:
        void info() const
        {
            std::cout << "This is a guided tour" << '\n';
        }
};

Tour * tour = new GuidedTour();
tour->info();
delete tour; // here you need the virtual destructor

And while we're at best practice; please avoid raw pointers. Even if you are bound to C++98, there are very good smartpointers out there; Boost for example provides shared_ptr and weak_ptr that closely resemble the ones in C++11.

nikolas
  • 8,707
  • 9
  • 50
  • 70
  • I have displayDetails method in Tour object. It's over written in GuidedTour object. How do I call these methods without casting it? sorry I'm new to C++ and points – Achintha Gunasekara Aug 30 '13 at 10:04
  • could you please explain this line? virtual ~Tour() {} – Achintha Gunasekara Aug 30 '13 at 10:06
  • @Archie I've updated my answer to show you how to call the function; explaining the `virtual` keyword would really bloat this answer, but you can find good explanations on SO, like http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained or http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors – nikolas Aug 30 '13 at 10:54