子对象作为参数
我想做类似以下的事情
virtual void Aircraft::getImage(GenericImage&)=0;
void Drone::getImage(Image&);
: Image
是 GenericImage
的子类 Drone
是 Aircraft
的子类。
如何要求 Drone 类具有 getImage(genericImage&) 的任何子类
方法,而编译器不会抱怨 genericImage
和 Image
不是同一个东西吗?我希望最终用户/开发人员能够使用自己的图像格式定义自己的无人机类,该图像格式扩展了 genericImage ,但无论他们创建什么,都必须提供从无人机获取图像的功能。
I want to do something like the following:
virtual void Aircraft::getImage(GenericImage&)=0;
void Drone::getImage(Image&);
whereImage
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不要带外参数,只需返回图像即可。返回类型允许协变。这意味着,只要
Image
实际上公开派生自GenericImage
,就可以了: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 fromGenericImage
, this will be fine:不可能以这种方式更改参数,也不应该这样做,因为它通常会违反里氏替换原则 (LSP):根据定义,
Aircraft::getImage
可以接受任何GenericImage< /code>,其中包括
GenericImage
的任意子类。子类必须符合该接口,因此也必须接受任何GenericImage
。但是,您明确希望指定它仅接受特定子类型Image
。请注意,返回类型的情况有所不同,因为它们代表函数产生的东西,而不是函数接受的东西(你可能会说你的< code>getImage 也会生成,但 C++ 不知道 out 参数的概念,并且您确实必须将现有对象传递给
getImage
才能用图像数据填充它)。由于对于返回类型,使用派生类型不会违反 LSP,C++ 确实允许这样做(该功能称为协变返回类型)。因此,解决方案是在函数内分配图像对象并返回该对象(最好使用指针 - 不幸的是,智能指针不适用于协变返回类型 - 来指示发生的分配)。也就是说,您的函数将读取但是很可能您只会使用基类接口,因此我更愿意仅使用接口中的
GenericImage
,而不是利用智能指针: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, anyGenericImage
, which includes arbitrary subclasses ofGenericImage
. A subclass has to conform to that interface, and therefore would also have to accept anyGenericImage
. However you explicitly want to specify that it only accepts the specific subtypeImage
.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 togetImage
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 readHowever 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: