2013-06-27 4 views
2

"모양"을 저장하기 위해 ptr_vector를 사용하고 있습니다. "원"과 같은 파생 된 모양 클래스로 채우기 위해 노력하고 있습니다. 그리고 그 (것)들을 내리려고 할 때마다 나는 나쁜 캐스트를 얻습니다.BOOST 및 C++ : 다형성이 작동하지 않는 것 같습니다.

class Shape 
{ 
public: 
    virtual ~Shape() {}; 
    virtual void print() { std::cout << "shape" << std::endl; }; 
}; 

class Circle : 
    public Shape 
{ 
public: 
    void print() { std::cout << "circle" << std::endl; }; 
}; 

int main() 
{ 
    boost::ptr_vector<Shape> shapes; 
    shapes.push_back(new Circle); 

    BOOST_FOREACH(Shape shape, shapes) 
    { 
     Circle& tempCircle = dynamic_cast<Circle&>(shape); 
     if(&tempCircle != NULL) 
      tempCircle.print(); 
    } 

    system("PAUSE"); 
} 

답변

6

문제가 shape는 그 유형 Shape 인 객체, 그리고 (동적) 형 Circle 인 오브젝트에 대한 참조 인 것이있다.

다형성은 참조 또는 포인터에서만 작동합니다. 객체를 으로 처리하고 파생 클래스의 객체에서 기본 클래스의 객체를 복사 또는 구성하는 경우 얻을 수있는 것은 slicing입니다. 확실히 원하는 것은 아닙니다.

대신을 시도해보십시오

BOOST_FOREACH(Shape& shape, shapes) 
//    ^

또한 아마 const에 대한 참조를 사용하는 것이 나을 - 당신이 그렇게 루프 내부에 참조 된 개체를 수정하지 않을 이후 :

BOOST_FOREACH(Shape const& shape, shapes) 
//     ^^^^^^ 
{ 
    Circle const& tempCircle = dynamic_cast<Circle const&>(shape); 
    //  ^^^^^^         ^^^^^^ 

    // ... 
} 

또한 C++ 11은 범위 기반 for 루프를 가지고 있으므로 BOOST_FOREACH 종류는 사용되지 않습니다. C++ (11)는 옵션입니다 그래서, 당신은 쓸 수 있습니다 : 이것은 말했다

for (auto const& shape : shapes) 
{ 
    Circle const& tempCircle = dynamic_cast<Circle const&>(shape); 
    //  ^^^^^^         ^^^^^^ 

    // ... 
} 

, 그것은 (as Chad does in the comments)을 지적하는 의미가 여기에 동적 내리 뜬을 수행 할 필요가 없습니다, print() 가상이기 때문에 기능. 일시 : Shape가 참조하는 객체가 Circle의 인스턴스 인 경우

shape.print(); 

함수 호출은 Circle::print()에 파견됩니다.

+0

이 또한 참고 인쇄'이후() '가상 함수이기 때문에,이 경우에는'dynamic_cast'는 불필요합니다. – Chad

+0

@Chad : 오, 맞아. 나는 그 부분을 놓쳤다. 감사합니다. –

+0

@Chad : shape.print()를 호출하려고하면 (자동 const & shape : 모양)을 사용할 때 객체에 멤버와 호환되지 않는 유형 한정자가 있다고합니다. function :( – dubesinhower

0

또한 dynamic_cast를 올바르게 사용하지 않습니다. reference를 dynamic_cast하고 객체가 실제로 캐스팅하는 클래스에 속하지 않으면 캐스팅은 std::bad_cast을 던집니다. null 주소를 가진 참조와 같은 것이 없으므로 null을 반환하지 않습니다. 그래서 여기에 올바른 방법 :

Circle* tempCircle = dynamic_cast<Circle*>(&shape); 
if(tempCircle != NULL) 
    tempCircle->print(); 

(. 당신은 실제로 &r == NULL에 대한 참조를 r이 있지만 동작을 보증되지 널 포인터를 역 참조 후 수)