C++中的多态与多重继承实现与Java的区别

2020-03-22 14:01:00王旭

从另一个角度理解,编译器在编译一个完整的 App 时确实能够推断所有变量的真实类型,但这需要联系过多上下文。编译一段代码却需要这段代码输入参数的除类型之外的上下文信息,并根据上下文信息生成不同的二进制文件,这是不可接受的。

Java 多态比较

由于 Java 的多态机制比 C++ 简单,理论上可以使用 C++ 的机制实现 Java 多态。但 C++ 跟 Java 有一点决定性的不同:C++ 要求父类成员方法必须有 Virtual 关键字修饰时才能被重写。这就意味着编译器在编译父类时就能确认那些函数可能被重写,于是可以对不可能重写的函数直接在编译时决定调用的具体函数,而对可能重写的函数使用虚指针表处理。而 Java 的方法默认都是可以重写的,因此可以认为 Java 方法调用都需要经过查询虚函数列表的过程,会比 C++ 不重写函数多一点开销。

Java 不支持多重继承,但 Java 支持接口 Interface, 接口跟多重继承有相似之处,不能简单的使用一个虚函数表查找。类需要为其实现的每个 Interface 生成一个虚函数列表,跟 C++ 的情况类似。OpenJDK 文档指出,在类定义中找到 Interface 的虚函数列表的办法是很粗暴的:在类实现的所有 Interface 列表中遍历查找。文档中指出,真正的多重继承是罕见的,通常可以归结为单继承。对此遍历过程可能有各种优化,笔者没有深入了解。

思考 Java 和 C++ 的一点不同:C++ 没有运行时类型,由编译器在编译时尽力保证指针指向的位置有对象正确的数据结构。将子类指针赋值给父类指针变量时,编译器尽力对其进行调整,但如果发生了 Void 指针赋值等,则编译器无法保证指针指向的位置有正确的对象数据结构。这一步只要语法上没有错误,就不会立即报错,编译器也无法确认是否会发生问题,一定要等到该指针实际进行解引用等发生异常才会报错。Java 有运行时类型,在将对象赋值给不同的类型的变量时,会在运行时进行类型检查,如果没有正确的类型继承关系,会在赋值时报错。

另外,对比 Java 的 Interface 和 C++ 的多重继承,会发现 Interface 的运行时时间开销要比 C++ 多重继承大得多。但是 C++ 多重继承需要为每个父类附加一个指针,并且编译器在编译时需要完成更多的工作。Java 相对于 C++ 是更加「强类型」的语言。

到此这篇关于C++中的多态与多重继承实现与Java的区别的文章就介绍到这了,更多相关C++ 多态与多重继承内容请搜索易采站长站以前的文章或继续浏览下面的相关文章希望大家以后多多支持易采站长站!