子对象作为参数

发布于 2024-12-26 04:54:40 字数 463 浏览 0 评论 0原文

我想做类似以下的事情

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

ImageGenericImage 的子类 DroneAircraft 的子类。

如何要求 Drone 类具有 getImage(genericImage&) 的任何子类 方法,而编译器不会抱怨 genericImageImage不是同一个东西吗?我希望最终用户/开发人员能够使用自己的图像格式定义自己的无人机类,该图像格式扩展了 genericImage ,但无论他们创建什么,都必须提供从无人机获取图像的功能。

I want to do something like the following:

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

where
Image is a subclass of GenericImage
Drone is a subclass of Aircraft.

How can I require the Drone class to have a getImage(any subclass of genericImage&) method without the compiler complaining that a genericImage and an Image are not the same thing? I want the end user/dev to be able to define their own drone class with their own Image format which extends genericImage but no matter what they create they MUST give the functionality to get an image from their drone.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

打小就很酷 2025-01-02 04:54:40

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

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

Don't take an out-parameter, simply return the image. Return-types are allowed to be covariant. That means, as long as Image actually publicly derives from GenericImage, this will be fine:

virtual GenericImage& Aircraft::getImage() = 0;
virtual Image& Drone::getImage();
眼眸里的那抹悲凉 2025-01-02 04:54:40

不可能以这种方式更改参数,也不应该这样做,因为它通常会违反里氏替换原则 (LSP):根据定义,Aircraft::getImage 可以接受任何 GenericImage< /code>,其中包括 GenericImage 的任意子类。子类必须符合该接口,因此也必须接受任何GenericImage。但是,您明确希望指定它仅接受特定子类型Image

请注意,返回类型的情况有所不同,因为它们代表函数产生的东西,而不是函数接受的东西(你可能会说你的< code>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(); }
};

It is not possible to change parameters this way, nor should it be because it would generally violate the Liskov Substitution Principle (LSP): Aircraft::getImage can accept, by definition, any GenericImage, which includes arbitrary subclasses of GenericImage. A subclass has to conform to that interface, and therefore would also have to accept any GenericImage. However you explicitly want to specify that it only accepts the specific subtype Image.

Note that the situation is different for return types, because those represent things the function produces instead of things the function accepts (you may say your getImage also produces, but C++ doesn't know the concept of an out parameter, and you indeed have to pass an existing object to getImage in order to fill it with the image data). Since for return types, going to a derived type doesn't violate the LSP, C++ indeed allows it (the feature is called covariant return types). Therefore the solution is to allocate the image object inside your function and return that (preferably using a pointer — a smart pointer unfortunately doesn't work for covariant return types — to indicate the allocation that takes place). That is, your function would read

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

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

However most likely you'll only use the base class interface anyway, therefore I'd prefer to just go with the GenericImage in the interface, and instead take advantage of smart pointers:

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

class Drone: public Aircraft
{
  virtual std::unique_ptr<GenericImage> getImate() { return new Image(); }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文