我目前正在设计一种编程语言,我很想知道如何解决这个问题:
假设我有一个看起来像这样的类(或接口):
class A { // size is 4 bytes
int32 a = 0;
}
和扩展它的第二个B类看起来像这样:
class B extends A { // size is 8 bytes
int32 b = 0;
}
我有一个看起来像这样的函数f:
int32 f(A first, A second) {
return first.a + second.a;
}
但是,如果我用两个B调用它,则second.a不会在同一个位置,就像用两个As调用它一样,因为第一个参数会移动它。我目前解决这个问题的想法是:
第二个想法是一个问题,因为它需要得到所有函数的支持,即使它们很少或从不使用子类型调用,这是低效的。
第三个想法需要创建很多函数(一个接受5个参数的函数,它可以是20个不同的子类型,需要生成100个相似的代码片段,如果它只被称为一个具有未知类型的参数),并且每个只有一个功能使用它的类需要一个vtable。此外,已编译库中的函数不能与新子类型一起使用。
组合2和3并创建相同函数的两个版本,一个只接受类型,另一个接受子类型也可以解决其中的一些问题。
我很好奇是否有更好的解决方案,以及C ++等其他语言如何实现这一点。
答案 0 :(得分:3)
在C ++中,使用子类型f(A)
的参数按值调用B
等同于
f(static_cast<const A&>(b));
static_cast
可能导致同一地址的内存被重新解释为较短数据块的开头,或者先透明地添加一些偏移(如果A
不是第一个基类或者是虚拟的)。之后,在内部,调用A
的复制构造函数。在任何一种情况下,B
添加的信息都会完全丢失,同时还会覆盖虚函数。出于所有目的,传递的内容不再是B
。
动态多态性需要引用或指针,这很大程度上是出于您概述的原因。但是,如果您想通过值&#34;传递&#34;引用,最简单的解决方案可能是将引用传递给对象的副本。请注意,在这种情况下,每个对象都需要知道&#34;调用正确的拷贝构造函数是什么类型,或者从公共超类派生并实现某种形式的clone()
。