2013-09-24 2 views
1

나는 유형이 일 때 자동으로의 가장 깊은 부분 인으로 해결 될 것이라고 생각했습니다. Cat 클래스 Animal에서 talk()을 무시하는 경우 Cat : Animal는 당신이, cat->talk()를 호출 할 경우, 고양이는 "야옹"이 아니라 몇 가지 이상한 일반 Animal가 기본 클래스 Animal에서 제공 불평 말할 것이다. 여기 상속 해상도

struct Animal 
{ 
    virtual void talkTo(Animal* o) { 
    puts("Animal-Animal") ; 
    } 
} ; 

struct Cat : public Animal 
{ 
    virtual void talkTo(Animal* o) { 
    puts("Cat-Animal") ; 
    } 
    virtual void talkTo(Cat* o) { 
    puts("Cat says meow to Cat") ; 
    } 
} ; 

일부 호출 코드입니다 :

그래서 나는 이것에 대해 혼란 스러워요 여기

Cat *cat = new Cat() ; 
    cat->talkTo(cat) ; //Cat says meow to Cat 

    Animal *animalCatPtr = cat ;  
    cat->talkTo(animalCatPtr) ; //Cat-Animal 

마지막 줄, 나는 Catcat->talkTo에 보내하지만 난 animalCatPtr을 사용하고 있습니다 . animalCatPtr은 여전히 ​​Cat을 참조하지만 아직까지는 함수 호출에서 단순히 Animal으로 해석됩니다.

통과 포인터가 실제로 계층 구조에서 가장 깊은 유형으로 확인되도록하려면? 나는 dynamic_cast<> 일련의 테스트를하고 싶지 않다. Animal이 실제로 있는지 알고 싶습니다. Cat 또는 Dog 또는 무엇을 가지고 있습니다.

+2

'void (Animal *)'멤버 함수 만 오버라이드됩니다. 다른 하나는'Cat'에서만 정의 된 * 새로운 * 오버로드입니다. –

답변

1

를 참조하십시오. 얼마나 까다 롭습니다.

기본적으로

wikipedia link 말한대로,

문제는 가상 함수가 C++에서 동적으로 파견하는 동안, 함수 오버로드는 정적으로 수행한다는 것입니다.

그럼, 당신이해야 할 것은 class Cat을 수정할 수 있습니다 : 지금

struct Cat : public Animal 
{ 
    virtual void talkTo(Animal* o) { 
    //puts("Cat-Animal") ; 
    o->talkTo(this) ; // TURN THE INVOKATION AROUND ("double dispatch") 
    } 
    virtual void talkTo(Cat* o) { 
    puts("Cat says meow to Cat") ; 
    } 
} ; 

,

cat->talkTo(animalCatPtr) ; 

animalCatPtr에서 것은 실제로Cat*이다. 그러나 talkTo 함수는 이것을 알지 못합니다. Cat::talkTo(Animal*)에서 "invokation을 뒤돌아 볼 때까지". animalCatPtr 실제로 단지 Animal 경우 해당 기능을 사용할 경우

, 우리는 가능한 경우 Animal::talkTo(Cat*)를 호출, 기본 클래스 Animal에서 생을 마감하거나 Animal::talkTo(Animal*) 것입니다.

animalCatPtr이 실제로 Cat 인 경우 우리는 결국 우리가 원하는 동작 인 Cat::talkTo(Cat*)을 호출하게됩니다.

2

당신은 두 번 파견의 형태를 원하는 당신이 이것을 달성하기 위해 "더블 파견"을 사용할 필요가 그래서 http://en.wikipedia.org/wiki/Double_dispatch

+0

다른 말로하면, 'dynamic_cast <>()' – bobobobo

+1

@bobobobo - 동적 디스패치에서는 동적 객체에 전달 된 기본 포인터를 사용하여 다른 멤버 함수에 다형 적으로 브리징합니다. –

+0

알았어, 알았다. 나는 [아래 답변에 더 많은 정보를 추가] (http://stackoverflow.com/a/18987136/111307) – bobobobo