Consider the following example of polymorphism in C++. To me, this is unexpected behavior, which probably lies in the fact that I am still thinking too much in Java. The question to me is now: How do I get the pointer example to call the more specific method.
#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);
}
The output of that program is:
value: Invoking process(RightImage& rightImage) with rightImage of type "RightImage"
shared_ptr: Invoking process(Image& image) with image of type "RightImage"
old fashioned pointer 1: Invoking process(Image& image) with image of type "RightImage"
old fashioned pointer 2: Invoking process(Image* image) with image of type "RightImage"
How can I make the last three examples also call process(RightImage&) and process(RightImage*)?
Next to the double dispatch as proposed by tokage, you could also have only 1 Process() function with the base class reference as parameter and then use polymorphism by calling virtual function of the base class inside the Process() function.