各语言对象和变量的关系
变量和对象
任何语言都是由变量和对象组成的。
变量和对象可能是存在一块的(变量代表内存,内存存放的的是对象二进制),也可能是分开存的,这种情况就是对象存放在其他内存,而变量存放的是那块内存的地址。
具体方式在不同语言中有很大区别,不同语言在底层可能做了很多优化,例如JVM的栈变量共享等。
1 |
|
对于上述代码,C++的话就是分配了两个值类型变量在不同栈空间,同时分配2个对,内存各自写3。
而对于java,也是分配了两个值类型变量在不同栈空间,但是对象3却是在栈空间单独存在的,值类型变量都是指向这个对象3,虽说是值类型,但是存放的也是地址。但是依然是值类型,有点像python的不可变对象传递。
变量类型
在各种语言中,变量一般分为值类型和引用类型。
值类型
变量直接存放对象的二进制数据(JVM的栈变量共享除外),如果对变量取地址,那么就是这段内存的地址名,例如”0xc00001c100”。
这里的内存空间一般是栈空间,变量和对象都是在栈空间的。
引用类型
引用类型的变量存放的是对象的地址,变量位于栈空间,而对象则是位于堆空间。例如a是引用变量,其内容是”0x12335423341“,这段地址是堆空间的地址,指向堆空间的对象,而自己的地址可能是”0x51314241“,是在栈空间的地址。
引用类型有个巨大的好处是自动垃圾回收GC,通过引用计数可以释放没有引用的对象。
不同语言总结
Java:
- 值类型:基本数据类型int/float/short/long/double/byte/char/bool
- 引用类型:其余全是
Python
- 全是引用类型,python的对象基本是heap空间
Go:
- 值类型:基本数据类型int, float,bool, string,以及数组和struct
- 引用类型:其余全是,Go存在指针
C++:
- 全是值类型
- 引用类型:通过指针,引用&,shared_ptr等实现。
栈空间堆空间
正如前文所说,栈空间一般是值类型的对象和变量空间,堆空间是引用变量的对象空间,堆空间一般都是new或malloc出来的,在C++中需要进行手动创建和释放,程序结束也不一定可以正确释放,容易造成内存泄漏(所以后面有类似java的shared_ptr,做引用计数的垃圾回收)。
除栈空间和堆空间,一般还有
- 静态空间:存放全局变量、static变量,在程序结束会自动释放
- 常量空间:类似java的string类型,final修饰的变量
- 代码空间:存放程序代码
java
- 对象分为基本数据类型和其他对象,同理变量也就分为基本数据类型的变量和引用变量
- 基本数据类型的变量操作,产生新的对象,不再指向同一个对象。变量传递相当于对象值传递。
1 |
|
- 引用变量操作,还是指向同一个对象,类似C/C++的指针/引用。变量操作相当于对象地址传递。
1 |
|
- 基本类型的变量和对象,引用变量都放在栈中,引用对象放在堆中。
- 栈空间的数据对象是共享的,但是堆空间是不共享的。
1 |
|
python
- 对象分为可变对象和不可变对象,同理变量也就分为不可变对象的变量和可变对象的变量
- 不可变对象(整型、字符串和元组)的变量操作,产生新的对象,不再指向同一个对象。变量传递相当于对象值传递。
1 |
|
- 可变对象的变量操作,还是指向同一个对象,类似C/C++的指针/引用。变量操作相当于对象地址传递。
1 |
|
C/C++
- 变量有变量的值和地址,对象有对象的值和地址
- 通过指针来实现对同一个对象的操作,指针的自由度更高,但是代码上相比java和python就更加复杂了,引用变量多方便啊。。
- C/C++也有指针的高级封装-引用!
1 |
|
- 即使是基本数据类型,也可以操作为同一个对象
1 |
|
各语言对象和变量的关系
http://yoursite.com/2020/01/07/编程开发/各语言对象和变量的关系/