2011-10-26 3 views
0

C++에서 다형성의 다음 예제를 고려하십시오. 나에게 이것은 예기치 않은 행동이다. 자바에서 여전히 너무 많은 것을 생각하고 있다는 사실에있다. 필자는 다음과 같은 질문을 던졌습니다.보다 구체적인 메서드를 호출하는 포인터 예제를 얻으려면 어떻게해야합니까?포인터가있는 다형성/boost :: shared_ptr

#include <iostream> 
#include <string.h> 
#include <boost/tr1/memory.hpp> 

class Image { 
public: 
    Image(std::string className = "Image") 
     : className_(className) 
    {} 

    virtual ~Image() {} 

    virtual std::string className() { 
    return className_; 
    } 

private: 
    std::string className_; 
}; 

class RightImage : public Image { 
public: 
    RightImage() 
     : Image("RightImage") 
    {} 
}; 

class Processor{ 
public: 
    void process(Image& image){ 
    std::cout << "Invoking process(Image& image) with image of type \"" << image.className() << "\"" << std::endl; 
    } 
    void process(RightImage& rightImage){ 
    std::cout << "Invoking process(RightImage& rightImage) with rightImage of type \"" << rightImage.className() << "\"" << std::endl; 
    } 

    void process(Image* image){ 
    std::cout << "Invoking process(Image* image) with image of type \"" << image->className() << "\"" << std::endl; 
    } 
    void process(RightImage* rightImage){ 
    std::cout << "Invoking process(RightImage* rightImage) with rightImage of type \"" << rightImage->className() << "\"" << std::endl; 
    } 
}; 

int main(int argc, char **argv) { 
     std::tr1::shared_ptr<Image> rightImageSharedPtr(new RightImage()); 
     Image* rightImagePointer = new RightImage(); 
     RightImage rightImage; 
     Processor processor; 
     std::cout << "value:     "; 
     processor.process(rightImage); 
     std::cout << "shared_ptr:    "; 
     processor.process(*rightImageSharedPtr); 
     std::cout << "old fashioned pointer 1: "; 
     processor.process(*rightImagePointer); 
     std::cout << "old fashioned pointer 2: "; 
     processor.process(rightImagePointer); 
} 

그 프로그램의 출력은 다음 호출 프로세스 (화상 & 이미지)와 :

값 : 유형 'RightImage "

있는 shared_ptr의 rightImage와 호출 프로세스 (RightImage & rightImage) "RightImage"유형의 이미지

구식 포인터 1 : 이미지를 호출하는 프로세스 (이미지 & 이미지)를 호출하는 중입니다. "RightImage"

구식 포인터 2 입력 유형 "RightImage"의 이미지로 호출 과정 (이미지 * 이미지)

가 어떻게 마지막 세 가지 예는 process(RightImage&)process(RightImage*) 호출 할 수 ? 당신이

std::tr1::shared_ptr<RightImage> rightImageSharedPtr(new RightImage()); 
    RightImage* rightImagePointer = new RightImage(); 

대안은 단지 더 복잡한 방법은 각 함수를 호출하기 전에 dynamic_cast는을 수행하는 것입니다 귀하의 변수를 선언해야하므로

+0

그리고 이것은 Java에서 작동해야합니까? – curiousguy

+0

@curiousguy 아니에요. 하지만 자바에서는 클래스 유형을 얻기 위해 리플렉션을 사용할 수 있습니다 ;-) – sebastiangeiger

답변

1

tokage가 제안한 double dispatch 옆에 Process() 함수 안에 기본 클래스의 가상 함수를 호출하여 다형성을 사용할 수 있습니다.

+0

예제에서 설명하는 방법은 아마 방문자 패턴을 요구할 것입니다. 그러나 구체적인 문제에서 가상의'process()'함수를 사용하여 얻었습니다. 'Image' 클래스와 다형성을 사용합니다. – sebastiangeiger

0

오버로드는 함수의 인수의 정적 유형에 해결 같은 일을하고있다.

+0

이상적으로'Image'는 제 인터페이스가 될 것이고 처리를 위해 Subtype을 전달할 것이기 때문에 이것은 제 설계에 정확히 적용되지 않습니다. – sebastiangeiger

+1

@sebastiangeiger : 하위 유형에 대한 별도의 오버로드가 없어야합니다. 모든 것은 공통 인터페이스를 통해 이루어져야합니다. –

1

당신이 문제를 해결하기 위해 이중 발송/방문자 패턴과 같은 것을 원한다고 생각합니다.

이미지를 실제로 인터페이스 아래에 입력하는 정보는 객체 내부에서만 사용할 수 있습니다. 따라서 이미지 객체에 가상 메서드를 호출하여 기본 유형으로 가져와야합니다.

예 : 물론

class Image{ 
    virtual void process(Processor &processor)=0; 
} 

class RightImage{ 
    virtual void process(Processor &processor){ 
     processor.process(this); 
    } 
} 

당신은 또한() 과정에서 이미지 클래스 내부의 처리를 할 수있는 - 방법,하지만 난 당신이 프로세서의 종류가 다른 종류의 이미지에 작업 할 생각한다. 또 다른 옵션 - 조금 더 깨끗한 - 이미지 유형에 대해 다른 단일 처리 단계에 대해 프로세서가 가상 메서드를 호출하도록하는 것입니다.

+0

자, 방문자 패턴 아이디어를 자신이 가지고 있어야합니다 :-) – sebastiangeiger