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 : 항상 가이드가 아닌 투어를 인쇄합니다.

어떻게 다형성 동작을 보관합니까?

상담 해주실 수 있습니까? (나는 ++ C에 새로 온) 내이 어떻게 다형성 작동하지 않습니다 C++ 98

많은 감사

+1

벡터 유형 때문입니다. 안내 된 객체를 추가하기위한 별도의 벡터 목록을 유지하십시오. – user1502952

+0

예, 둘러보기 개체에 대한 포인터 목록이 있습니다. 따라서 목록을 참조하면 항상 둘러보기 *가 생성됩니다. GuidedTour *를 거기에 밀어 넣으면 안됩니다 - 컴파일러는 Tour *로 캐스팅하려고합니다. 그러면 나중에 문제가 발생합니다. – HvS

+0

학교 과제물 일 때, 단일 벡터를 사용하여 값을 검색해야합니다. –

답변

5

을 사용하는 데 필요합니다.

어떻게

dynamic_cast<T>을 뭘 하려는지 달성하기는 다형성 유형 유형 T의 사실 여부를 확인하기 위해 RTTI를 사용하지만

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에 묶여 있더라도 아주 좋은 스마트 포인터가 있습니다. 부스트는 예를 들어 shared_ptrweak_ptr을 C++ 11과 매우 유사하게 제공합니다.

+0

Tour 객체에 displayDetails 메소드가 있습니다. 그것은 GuidedTour 객체에 작성되었습니다. 어떻게 이러한 메서드를 캐스팅하지 않고 호출 할 수 있습니까? 죄송합니다 C++을 처음 접했고 –

+0

포인트를 설명해 주시겠습니까? virtual ~ Tour() {} –

+0

@Archie 함수를 호출하는 방법을 보여주기 위해 내 대답을 업데이트했습니다. 'virtual' 키워드를 설명하면이 대답이 실제로 부 풀릴 것이지만, http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained 나 http : // stackoverflow와 같은 좋은 설명을 찾을 수 있습니다. com/questions/461203/when-to-use-virtual-destructors – nijansen