Ошибка проверки типа С++

Я следовал инструкциям, которые я получил из моего последнего поста, и переписал свой код.

Мой заголовочный файл

#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();
};

Затем у меня есть функция для заполнения вектора «список» объектами Tour и GuideTour.

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";
        }
    }
}

Однако мне всегда кажется, что возвращаются объекты Tour. Например: он всегда печатает NOT Guided Tour.

как архивировать полиморфное поведение?

Не могли бы вы посоветовать? (Я новичок в C++) Мне необходимо использовать C++98

Большое спасибо


person Achintha Gunasekara    schedule 30.08.2013    source источник
comment
Это связано с типом вектора‹Tour*›. Сохраните отдельный список векторов для добавления объектов гида.   -  person user1502952    schedule 30.08.2013
comment
Да, у вас есть список указателей на объекты Tour... следовательно, обращение к списку всегда будет давать Tour*. Не следует запихивать туда GuidedTour* — компилятор попытается преобразовать их в Tour*, а это означает проблемы в дальнейшем.   -  person HvS    schedule 30.08.2013
comment
Это для школьного задания, мне нужно использовать один вектор и извлекать из него значения.   -  person Achintha Gunasekara    schedule 30.08.2013
comment
как архивировать полиморфное поведение? спасибо   -  person Achintha Gunasekara    schedule 30.08.2013
comment
@HvS: Конечно, компилятор преобразует указатель. Он не будет преобразовывать то, что указывает указатель на. То есть и остается объектом GuidedTour.   -  person MSalters    schedule 30.08.2013


Ответы (1)


Это не то, как работает полиморфизм.

Как добиться того, что вы пытаетесь сделать

dynamic_cast<T> использует RTTI, чтобы проверить, действительно ли полиморфный тип относится к типу T:

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

Однако RTTI обходится дорого; эти проверки выполняются во время выполнения и замедляют вашу производительность, а RTTI может вообще не поддерживаться.

Что вы обычно должны делать

Избегайте необходимости знать точный тип вашего полиморфного объекта. Обеспечьте интерфейс, который будет хорошо работать в любом случае, и полагайтесь на вызов ваших виртуальных методов для выполнения этой работы.

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

И пока мы находимся в лучшей практике; пожалуйста, избегайте необработанных указателей. Даже если вы привязаны к C++98, есть очень хорошие умные указатели; Boost, например, предоставляет shared_ptr и weak_ptr, очень похожие на те, что есть в C++11.

person nijansen    schedule 30.08.2013
comment
У меня есть метод displayDetails в объекте Tour. Это перезаписано в объекте GuidedTour. Как мне вызвать эти методы без их приведения? извините, я новичок в C++ и точках - person Achintha Gunasekara; 30.08.2013
comment
не могли бы вы объяснить эту строку? виртуальный тур () {} - person Achintha Gunasekara; 30.08.2013
comment
@Archie Арчи, я обновил свой ответ, чтобы показать вам, как вызывать функцию; объяснение ключевого слова virtual действительно раздуло бы этот ответ, но вы можете найти хорошие объяснения по SO, например stackoverflow.com/questions/1306778/ или stackoverflow.com/questions/461203/ - person nijansen; 30.08.2013