2013-08-30 2 views
1

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

Моего заголовок файл

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

Тогда у меня есть функция, чтобы заселить в «список» вектор с туром и объектами guidedTour.

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

Однако я всегда возвращаюсь к объектам тура. EG: он всегда печатает NOT Guided Tour.

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

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

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

+1

Это из-за вектора типа. Сохраняйте отдельный векторный список для добавления объектов guidtour. – user1502952

+0

Да, у вас есть список указателей на объекты Tour ... поэтому ссылка на список всегда даст Tour *. Нельзя толкать GuidedTour * там - компилятор попытается отбросить их в Tour *, а это значит, что проблема позже. – HvS

+0

Это для школьного задания, я должен использовать один вектор и извлекать из него значения –

ответ

5

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

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

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, там есть очень хорошие smartpointers; Например, Boost предоставляет shared_ptr и weak_ptr, которые очень похожи на те, что указаны на C++ 11.

+0

есть дисплейDetails способ в турне объект. Все написано в объекте GuidedTour. Как я могу назвать эти методы без его литья? извините, что я новичок в C++, и очки –

+0

не могли бы вы объяснить эту строку? virtual ~ Tour() {} –

+0

@Archie Я обновил свой ответ, чтобы показать вам, как вызвать функцию; объяснение ключевого слова 'virtual' действительно раздуло бы этот ответ, но вы можете найти хорошие объяснения на SO, например http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained или http: // stackoverflow. ком/вопросы/461203 /, когда в использовании-виртуальные-деструкторов – nijansen

Смежные вопросы