子对象作为参数

时间:2012-01-10 23:48:56

标签: c++ inheritance virtual subclass

我想做以下事情:

virtual void Aircraft::getImage(GenericImage&)=0;
void Drone::getImage(Image&);

,其中 ImageGenericImage的子类 DroneAircraft的子类。

如果没有编译器抱怨getImage(any subclass of genericImage&)genericImage不是同一个东西,我怎么能要求Drone类有Image方法?我希望最终用户/ dev能够使用自己的图像格式定义自己的无人机类,该格式扩展genericImage,但无论他们创建什么,他们必须提供从无人机获取图像的功能。

2 个答案:

答案 0 :(得分:1)

不要取出参数,只需返回图像即可。返回类型允许协变。这意味着,只要Image实际上公开来自GenericImage,就可以了:

virtual GenericImage& Aircraft::getImage() = 0;
virtual Image& Drone::getImage();

答案 1 :(得分:0)

不可能以这种方式更改参数,也不应该因为它通常违反Liskov替换原则(LSP):Aircraft::getImage可以接受任何GenericImage,包括GenericImage的任意子类。子类必须符合该接口,因此还必须接受任何GenericImage。但是,您明确要指定它只接受特定子类型Image

请注意,返回类型的情况不同,因为它们表示函数生成而不是函数接受的内容(您可以假设您的getImage也产生了,但是C ++不知道out参数的概念,并且您确实必须将现有对象传递给getImage以便用图像数据填充它。因为对于返回类型,转到派生类型并不违反LSP,C ++确实允许它(该特征称为协变返回类型)。因此,解决方案是在函数内部分配图像对象并返回(最好使用指针 - 不幸的是,智能指针不适用于协变返回类型 - 以指示发生的分配)。也就是说,你的函数会读取

class Aircraft
{
  virtual GenericImage* getImage() = 0;
};

class Drone: public Aircraft
{
  virtual Image* getImate() { return new Image(); }
};

然而,最有可能你只会使用基类接口,因此我更喜欢在界面中使用GenericImage,而是利用智能指针:

class Aircraft
{
  virtual std::unique_ptr<GenericImage> getImage() = 0;
};

class Drone: public Aircraft
{
  virtual std::unique_ptr<GenericImage> getImate() { return new Image(); }
};