C 多态和java多态_C++与Java多态的区别

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

在C++中

普通函数调用:具体调用哪个方法在编译时就可以决定(通过查找编译器的符号表),同时在使用标准过程调用机制基础上增加一个表示对象身份的指针(this指针)。

虚函数调用:函数调用依赖于对象的实际类型,一般地说,对象的实际类型只能在运行时间才能确定。实现机制是使用virtual table(vtbls)和virtual table pointers(vptrs)。

vtbl 是由函数指针构成的数组或链表,程序中每一个class凡声明(或继承)虚函数者,都有一个自己的vtbl,其中的条目就是该class的各个虚函数实现的指针。因此必须为每一个class消耗一个vtbl空间,其大小视虚函数的个数确定。

凡声明有虚函数的class,其对象都有一个隐藏的data member,用来指向class的vtbl。

当多态发生时,编译器首先根据对象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

#include

#include

#include

using namespace std;

class A

{

public:

virtual void fun()

{

cout<

}

A()

{

fun();

}

};

class B : A

{

public:

virtual void fun()

{

cout<

}

B()

{

fun();

}

};

int main(int argc, char *argv[])

{

B b;

}

//A

//B

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值