Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 编译后,类声明和定义如何存储在面向对象语言(C+;+;)中?_Java_C++_Class_Oop_Compilation - Fatal编程技术网

Java 编译后,类声明和定义如何存储在面向对象语言(C+;+;)中?

Java 编译后,类声明和定义如何存储在面向对象语言(C+;+;)中?,java,c++,class,oop,compilation,Java,C++,Class,Oop,Compilation,我了解C程序的内存是如何组织的(堆栈、堆、函数调用等)。 现在,我真的不明白所有这些东西在面向对象语言(更具体地说,是C++)中是如何工作的 我知道每当我使用new关键字时,对象的空间都会分配到堆上 关于这一点,我的一些基本问题是: 1)在程序执行期间,类定义是否存储在内存中的某个位置 2)如果是,则存储在何处以及如何存储。如果否,那么在运行时如何调度函数(对于虚拟/非虚拟函数) 3)为对象分配内存时,该对象的所有详细信息都存储在内存中吗?(它所属的类别、成员函数、公私变量/函数等) 因此,基本

我了解C程序的内存是如何组织的(堆栈、堆、函数调用等)。 现在,我真的不明白所有这些东西在面向对象语言(更具体地说,是C++)中是如何工作的

我知道每当我使用new关键字时,对象的空间都会分配到堆上

关于这一点,我的一些基本问题是:

1)在程序执行期间,类定义是否存储在内存中的某个位置

2)如果是,则存储在何处以及如何存储。如果否,那么在运行时如何调度函数(对于虚拟/非虚拟函数)

3)为对象分配内存时,该对象的所有详细信息都存储在内存中吗?(它所属的类别、成员函数、公私变量/函数等)

因此,基本上,有人能解释一下在编译之后/编译过程中如何转换面向对象的代码,从而实现这些O.O.p.特性吗

我对Java/C++很熟悉。因此,您可以用这两种语言中的任何一种来解释逻辑,因为这两种语言都有非常不同的特性

另外,请添加任何参考链接,以便我也可以从那里阅读,以防出现进一步的疑问

谢谢

1) 在程序执行期间,类定义是否存储在内存中

<>爪哇中的C++,是的。< /P> 2) 如果是,则存储在何处以及如何存储。如果否,那么在运行时如何调度函数(对于虚拟/非虚拟函数)

<>在C++中,调用非虚函数的编译器由函数的实际静态地址代替;对虚拟函数的调用通过
new
被转换为内存分配(编译器知道精确的大小),然后调用(静态确定的)构造函数。编译器将字段访问转换为从对象开始以静态已知偏移量访问内存

它在Java中类似——特别是,虚拟表用于虚拟调用——只是字段访问可以象征性地完成

3) 当一个对象被分配内存时,该对象的所有细节都存储在内存中吗?(它所属的类别、成员函数、公私变量/函数等)

在C++中没有存储元数据(除了需要的一些位之外)。在Java中,您可以获得所有成员的类型信息和可见性以及其他一些信息—您可以查看以了解更多信息

因此,基本上,有人能解释一下在编译之后/编译过程中如何转换面向对象的代码,从而实现这些O.O.p.特性吗

正如你从我上面的回答中所看到的,这实际上取决于语言

在C++语言中,重编译是由编译器完成的,而产生的代码与面向对象的概念几乎没有关系。事实上,C++编译器的典型目标语言(本机二进制代码)是非类型化的。


在java语言中,编译器的目标是中间的表示,通常包含很多额外的细节-类型信息,成员可见性等。这也是在这些语言中所能做到的。

细节可能有所不同,但通常对于每个C++类,我们都有:

  • 一组方法,每个方法都只是一个函数
  • 虚方法表:一个数组,其中每个元素引用此类或其超类之一的方法
没有虚拟方法的对象就是C中的结构。一旦声明了虚拟方法,对象就会得到一个引用虚拟表的隐藏字段(下面,
vmt

<> >调用非虚方法<代码> Obj.m(ARG)< /C> >转换为C类函数<代码> M $(Obj/ARG)< /C> >其中代码> M $ < /C>是由C++编译器生成的一些人工标识符,以区别于其他类中的命名方法>代码> M>代码>。 调用虚拟方法
obj.m(arg)
将转换为
(obj->vmt[N])(obj,arg)
,也就是说,实际函数取自对象的虚拟表。每个方法在表中都有自己的编号。这个数字在编译时已知,并硬编码到调用指令序列中

运行时不会保存/使用任何其他信息以供正常执行。可以保留更多信息用于调试目的

在程序执行期间,类定义是否存储在内存中

定义不会被保留——至少在维护编译时的信息的意义上不会

当一个对象被分配内存时,该对象的所有细节都存储在内存中吗?(它所属的类别、成员函数、公私变量/函数等)

在编译过程中,对字段的引用之类的内容会转换为具有固定偏移量的指针的解引用。例如,
a->first
可能被翻译成类似于
*(a+4)
a->second
的内容,如
*(a+8)
等。实际数量将取决于前面字段的大小、目标体系结构等

类似的情况也适用于对象的大小(用于分配和解除分配)

简而言之,对象的大小及其字段的偏移量在编译时是已知的,它们在实际二进制文件中被替换

如果否,那么在运行时如何调度函数(对于虚拟/非虚拟函数)

虚拟方法调用之类的东西通常以与字段类似的方式进行转换,因为它们也可以被视为“字段”