自己动手验证java和C++在动态性上的区别 求大侠斧正

本文通过实验对比了Java和C++在动态性上的差异,详细解析了Java如何通过延迟编译和动态连接类来实现动态特性的优势,以及C++在类更新时重新编译的必要性。实验通过修改源代码并观察运行结果,直观展示了两种语言在动态性上的不同处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自己动手验证java和c++在动态性上的区别 求大侠斧正

以下是对java动态性学习时网上看到的一段话:

//==============引用====start===================================

自http://book.51cto.com/art/200709/55217.htm

java 语言具有动态特性。java 动态特性是其面向对象设计方法的扩展,允许程序动态地装入运行过程中所需的类,这是 c++ 进行面向对象程序设计所无法实现的。c++ 程序设计过程中,每当在类中增加一个实例变量或一种成员函数后,引用该类的所有子类都必须重新编译,否则将导致程序崩溃。java采取如下措施来解决此类问题。

(1)java编译器不是将对实例变量和成员函数的引用编译为数值引用,而是将符号引用信息在字节码中保存后传递给解释器,再由解释器在完成动态连接类后,将符号引用信息转换为数据偏移量。存储器生成的对象不在编译过程中决定,而是延迟到运行时由解释器确定。这样,对类中变量和方法进行更新时就不至于影响现存的代码。解释执行字节码时,这种符号信息的查找和转换过程仅在一个新的名字出现时才进行一次,随后代码便可以全速执行。(2)在运行时确定引用的好处是可以使用已被更新的类,而不必担心会影响原有的代码。如果程序连接了网络中另一系统的某一类,该类的所有者也可以自由地对该类进行更新,而不会使任何引用该类的程序崩溃。

(3)java还简化了使用一个升级的或全新的协议的方法。如果系统运行 java 程序时遇到了不知怎样处理的程序,没关系, java 能自动下载你所需要的功能程序。

java是一种比c/c++更具动态特性的语言。在设计上强调为运行中的运算环境提供支持。java是在运行时为模块与模块之间建立连接,并能够更直接地运用面向对象设计体系。程序库可以自由地增加新方法和实例变量,而不会对它们的客户产生任何影响。

//===============引用===end===================================

接下来是我做的实验 分两部分 主要是以代码 辅助说明的形式阐述

一.首先验证java

/*a.java*/

public class a{

public int i=0;

public int j=1;

public int k=1;

}

/*ua.java*/

public class ua{

publica a;

public void aa(){

a= new a();

system.out.println(a.i);

} }

/*dom.java*/

public class dom{

public static void main(string args[]){

ua ua=new ua();

ua.aa();

}

}

1 命令提示符中 javac a.java

javac b.java

javac dom.java产生三个相应的 .class文件

java dom控制台 输出0

2 将b.java 删除 保证b不能被编译成新的b.class

改动a.java变量最后添加 int jj=99;

删除原a.clss

javac a.java 产生新a.class 且被保证是新产生的

java dom控制台输出0

说明a的源代码改动了 且编译出新的.class但是原有的b.class还是可以运行

//-----------------------------------------------------------------------------------------------------------------

二.对c++进行实验

/*a.cpp*/

classa{

public:

int geti()

{return i;}

void seti(int newi)

{

i=newi;

}

public:

int i;

int j;

};

/*b.cpp*/

#include"a.cpp"

#include

using namespace std;

class b

{

a aa;

public:

void pr()

{

// aa=new a();

aa.i=99;

cout

using namespace std;

void main(){

b bb;

bb.pr();

}

1. 编译 a.cpp b.cpp dom.cpp 产生 a.obj b.objdom.objbuild 产生d.exe 执行输出99

2.删除 d.exe

将 b.cpp 删除保证b不能被重新编译 删除a.obj代码不做改动

编译a.cpp 产生新的a.objbuild 产生d.exe 执行可输出99

3. 还原到原始状态 把b.cpp放回来

编译 a.cpp b.cpp dom.cpp 产生 a.obj b.objdom.objbuild 产生d.exe 执行输出99

4.删除 d.exe

将 b.cpp 删除保证b不能被重新编译 删除a.obj在a.cpp 变量中加入 int jjjj;

编译a.cpp 产生新的a.objbuild 产生报错 找不到b.cpp

5. 还原到原始状态 把b.cpp放回来 a.cpp改回最初状态

编译 a.cpp b.cpp dom.cpp 产生 a.obj b.objdom.objbuild 产生d.exe 执行输出99

6.删除 d.exe

删除a.obj在a.cpp 变量中加入 int jjjj;

编译a.cpp 产生新的a.obj编译b.obj build 产生d.exe 执行可输出99

说明a.cpp不改动时 重新编译得到a.obj 和原始b.obj可以连接产生.exe

而 a.cpp改动时重新编译得到a.obj和原始b.obj 不能连接了,需要重新编译b

//----------------------------------------------------------------------------------------------------------

根据实验结果加上上面一段引用文字 猜测如下:

java在编译时 在b.class中只保存了需要用到的a.i这个引用 到了运行时才会哪这个引用到a.class中去找到a.i的实际偏移量。所以哪怕a.class随时改变 只要有a.i 运行时都能获得正确最新的a.i;

而c++在编译时 b.obj中不只保存了需要用到的a.i这个引用 并且保存了a.i在a.class中的实际偏移量。所以a.obj改变了b.obj也就不能用了,因为保存了过时的a.i的偏移量。

步骤虽然很罗嗦,但是目的是想验证的更加严谨。在这分享给大家看看,也当自己的一个小总结。不知道我上面的猜测是否符合实际情况,请各位大侠斧正。

田旭园奚亮亮

2011.7.1 于419宿舍


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值