Domanda

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

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top