多态是指用父指针指向不同子类对象时,调用其共有的函数,不同的子类会有不同的行为。虽然C++和Java都具有多态机制,但是他们的实现不同,使用时的效果也会略有不同。

在C++中

  • 普通函数调用:具体调用哪个方法在编译时就可以决定(通过查找编译器的符号表),同时在使用标准过程调用机制基础上增加一个表示对象身份的指针(this指针)。
  • 虚函数调用:函数调用依赖于对象的实际类型,一般地说,对象的实际类型只能在运行时间才能确定。实现机制是使用virtual table(vtbls)和virtual table pointers(vptrs)。
    1. vtbl 是由函数指针构成的数组或链表,程序中每一个class凡声明(或继承)虚函数者,都有一个自己的vtbl,其中的条目就是该class的各个虚函数实现的指针。因此必须为每一个class消耗一个vtbl空间,其大小视虚函数的个数确定。
    2. 凡声明有虚函数的class,其对象都有一个隐藏的data member,用来指向class的vtbl。
    3. 当多态发生时,编译器首先根据对象vptr找出其vtbl,然后找出vtbl内对应的函数指针,最后调用函数指针指向的函数。从而实现多态。

在Java中

1.C++中VTable和vptr是在编译阶段由编译器自动生成的,也就是说,在C++程序载入内存以前,在.obj(.o)文件中已经有这些结构的信 息;Java中的方法表是由JVM生成的,因此,使用javac命令编译后生成的.class文件中并没有方法表的信息。只有等JVM把.class文件 载入到内存中时,才会为该.class文件动态生成一个与之关联的方法表,放置在JVM的方法区中。

2. C++中某个方法在VTable的索引号是在编译阶段已经明确知道的,并不需要在运行过程中动态获知;Java中的方法初始时都只是一个符号,并不是 一个明确的地址,只有等到该方法被第一次调用时,才会被解析成一个方法表中的偏移量,也就是说,只有在这个时候,实例方法才明确知道自己在方发表中的偏移 量了,在这之前必须经历一个解析的过程。

因此在构造函数是Java会发生多态,即使子类此时还没有构造完全(一个极难发现的bug)。而C++则不会发生多态,待父类构造完全,在构造子类。

Java代码如下:

public class A {
public void fun()
{
System.out.println("A");
}
public A()
{
this.fun();
}
}
public class B extends A{
public void fun()
{
System.out.println("B");
} public B()
{
fun();
}
public static void main(String [] argv)
{
B b = new B();
}
}
//B
//B

C++代码如下:

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
using namespace std;
class A
{
public:
virtual void fun()
{
cout<<"A"<<endl;
}
A()
{
fun();
}
};
class B : A
{
public:
virtual void fun()
{
cout<<"B"<<endl;
}
B()
{
fun();
} };
int main(int argc, char *argv[])
{
B b;
}
//A
//B

可以发现,C++构造子类时,先构造父类,输出A,然后在构造自身,输出B。而Java在构造子类时,父类并未构造完成,但已经可以发生多态输出B,然后再构造自身,输出B。Java一般为了避免这种情况,会把fun等init()函数声明为private或者finial。

C++与Java多态的区别的更多相关文章

  1. C++和java多态的区别

    C++和java多态的区别 分类: Java2015-06-04 21:38 2人阅读 评论(0) 收藏 举报  转载自:http://www.cnblogs.com/plmnko/archive ...

  2. 深入理解java多态没有烤山药的存在,java就不香了吗?

    目录 1. 从吃烤山药重新认识多态 2. 多态前提条件[重点] 3. 多态的体现 4. 多态动态绑定与静态绑定 5. 多态特性的虚方法(virtual) 7. 向上转型 8. 向下转型 9. 向上向下 ...

  3. (转载)图解Java多态内存分配以及多态中成员方法的特点

    图解Java多态内存分配以及多态中成员方法的特点   图解Java多态内存分配以及多态中成员方法的特点   Person worker = new Worker(); 子类实例对象地址赋值给父类类型引 ...

  4. Java多态的实现机制是什么,写得非常好!

    作者:crane_practice www.cnblogs.com/crane-practice/p/3671074.html Java多态的实现机制是父类或接口定义的引用变量可以指向子类或实现类的实 ...

  5. C++与Java的语法区别

    C++与Java的语法区别 首先,两个大的不同是主函数和怎样编译的不同,接下来是许多小的区别. main 函数C++//自由浮动的函数int main( int argc, char* argv[]) ...

  6. Java 多态——与C++的比较

    学习了Java和C++之后,由于长期不使用C++,而java的基础知识掌握不牢,现在已经搞不清java多态了.现在先来谈谈java多态,稍后有时间再更新C++的多态,并进行比较~ 一. Java的多态 ...

  7. 深入理解Java多态机制

    从字节码层面来看,Java中的所有方法调用,最终无外乎转换为如下几条调用指令. invokestatic: 调用静态方法. invokespecial: 调用实例构造器<init>方法,私 ...

  8. java的版本区别、下载、配置

    参考:http://blog.csdn.net/liujun13579/article/details/7684604 java的版本区别 常用的 java 程序分为  Java SE.Java EE ...

  9. Java 多态 父类和子类方法的访问控制权限

    Java 多态 父类和子类方法的访问控制权限 @author ixenos 父类和子类方法的访问控制权限 继承是为了扩展类的功能,而这种扩展显然就是对一个原始类的扩展,目的还是向上转型来调用,所以这就 ...

随机推荐

  1. 自学Linux命令的四种方法

    自学Linux命令的四种方法 导读 童鞋们刚接触linux时,在学习过程中中会遇到不少问题,学习linux摸不着头脑,那么下面介绍四种linux的学习方法,特别适合新手. 方法一:终端"每日 ...

  2. Golang学习 - 学习资源列表

    Golang 学习资源: <Go 语言圣经(中文版)>  - 书籍 http://shinley.com/index.html <学习 Go 语言> - 书籍 http://w ...

  3. 如何编写自己的Linux安全检查脚本?

    因为本人工作中要涉及到很多东西,审计(日志.数据神马的).源代码审计.渗透测试.开发一大堆东西,有些东西,越是深入去做,越会发现,没有工具或脚本,工作起来是有多么的坑. 工作的这段时间,自己写了几个工 ...

  4. Myeclipse2014添加mybatis generator插件

    Myeclipse2014把mybatis generator插件直接放在dropins文件夹下,重启后不能成功安装mybatis插件. 既然离线安装不成功,可以选择在线安装 1.选择 Help-&g ...

  5. hadoop环境安装及简单Map-Reduce示例

    说明:这篇博客来自我的csdn博客,http://blog.csdn.net/lxxgreat/article/details/7753511 一.参考书:<hadoop权威指南--第二版(中文 ...

  6. Android(java)学习笔记63:线程的优先级

    1. Java线程的优先级从1到10级别,值越大优先级越高线程默认优先级是5.值越大优先级越高 (1) 继承自Thread类创建线程类: package cn.itcast_04; public cl ...

  7. 【原创】一些常用的Vi命令,可帮助脱离鼠标

    使用Vi编写代码时,如果想脱离鼠标,需要使用一些命令快捷键,下面罗列了一些常用的并且容易记住的: 1. 命令模式下,移动光标或跳转 0到行首 ^到行首第一个非空字符 $到行尾非空字符 fx向后移动光标 ...

  8. 精通CSS高级Web标准解决方案(1-1选择器)

    设计代码的结构 使用有意义的标记 css可以控制页面的外观并将表现与内容分隔开. 在分配ID与类名时尽量保证有意义且与表现无关. div可以对块级元素进行分组,而span可以对行内元素进行分组或标识. ...

  9. Gvim 在进行文件对比时报cannot read or write temp files

    本机环境为win7 64位旗舰版,gvim安装的是GVim7.4.解决办法如下: 在安装目录下有个"_vimrc"文件.修改19行.将 if &sh =~ '\<cm ...

  10. 怒刷DP之 HDU 1176

    免费馅饼 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status  ...