考虑以下C ++中的多态性示例。对我来说,这是意想不到的行为,这可能在于我在Java中仍然在思考太多。我现在的问题是:如何获得指针示例来调用更具体的方法。
#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);
}
该程序的输出是:
value:使用类型为“RightImage”的rightImage调用进程(RightImage&amp; rightImage)
shared_ptr:使用“RightImage”类型的图像调用进程(图像和图像)
老式指针1:使用“RightImage”类型的图像调用进程(图像和图像)
老式指针2:使用“RightImage”类型的图像调用进程(图像*图像)
如何让最后三个示例也调用process(RightImage&)
和process(RightImage*)
?
答案 0 :(得分:1)
我认为您需要像双重调度/访客模式这样的东西来解决您的问题。
只有在对象内部才能在界面下键入您的图像的信息。因此,您需要在图像对象上调用虚方法以获取基础类型。
示例:
class Image{
virtual void process(Processor &processor)=0;
}
class RightImage{
virtual void process(Processor &processor){
processor.process(this);
}
}
当然你也可以在process() - Method中对图像类进行处理,但我怀疑你想要不同类型的处理器来处理不同类型的图像。 另一种选择 - 可能更清洁 - 是让处理器为单个处理步骤调用虚拟方法,它们对于图像类型而言是不同的。
答案 1 :(得分:1)
在tokage提出的double dispatch旁边,你也可以只有一个Process()函数,基类引用作为参数,然后通过调用Process()中基类的虚函数来使用多态功能
答案 2 :(得分:0)
对函数参数的静态类型解析重载,因此需要将变量声明为
std::tr1::shared_ptr<RightImage> rightImageSharedPtr(new RightImage());
RightImage* rightImagePointer = new RightImage();
另一种方法是在调用每个函数之前执行dynamic_cast,这只是一种更复杂的做同样事情的方法。