【问题标题】:Polymorphism with pointers/boost::shared_ptr带指针/boost::shared_ptr 的多态性
【发布时间】:2011-10-26 19:31:28
【问题描述】:

考虑以下 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);
}

该程序的输出是:

值:使用“RightImage”类型的 rightImage 调用进程(RightImage& rightImage)

shared_ptr:使用“RightImage”类型的图像调用进程(图像和图像)

老式指针1:使用“RightImage”类型的图像调用进程(图像和图像)

老式指针 2:使用“RightImage”类型的图像调用进程(Image* 图像)

我怎样才能让最后三个示例也调用process(RightImage&amp;)process(RightImage*)

【问题讨论】:

  • 这应该在 Java 中工作?
  • @curiousguy 不,不是。但在 Java 中,我可以使用反射来获取类类型 ;-)

标签: c++ operator-overloading polymorphism


【解决方案1】:

在tokage 提出的double dispatch 旁边,您也可以只有1 个以基类引用作为参数的Process() 函数,然后通过在Process() 函数中调用基类的虚函数来使用多态性。

【讨论】:

  • 我在示例中描述它的方式可能会要求访问者模式,但是在我的具体问题中,我在Image 类中使用虚拟process() 函数并使用多态性。
【解决方案2】:

我认为您需要类似双重调度/访客模式来解决您的问题。

界面下的图像类型信息仅在对象内部可用。所以你需要在图像对象上调用一个虚方法来获取你的底层类型。

例子:

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

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

当然,您也可以在 process()-Method 中的图像类内部进行处理,但我怀疑您希望不同类型的处理器处理不同类型的图像。 另一种选择(可能更简洁)是让处理器为单个处理步骤调用虚拟方法,其中它们因图像类型而异。

【讨论】:

  • 好的,我自己应该有访问者模式的想法 :-)
【解决方案3】:

在函数参数的静态类型上解决了重载问题,因此您需要将变量声明为

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

另一种方法是在调用每个函数之前执行 dynamic_cast,这只是做同样事情的一种更复杂的方式。

【讨论】:

  • 理想情况下,Image 是我的接口,我会传入它的子类型进行处理,所以这并不完全适用于我的设计。
  • @sebastiangeiger:如果这是您的设计,您根本不应该为子类型拥有单独的重载。一切都应该通过通用接口完成。
猜你喜欢
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-04
  • 2020-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多