| 赞 | 63 |
| VIP | |
| 好人卡 | |
| 积分 | 76 |
| 经验 | |
| 最后登录 | 2024-6-8 |
| 在线时间 | 2566 小时 |
- 梦石
- 2
- 星屑
- 5550
- 在线时间
- 2566 小时
- 注册时间
- 2012-2-9
- 回帖
- 947

|
发表于 2016-7-17 17:10:19
|
显示全部楼层
本帖最后由 garfeng 于 2016-7-18 15:16 编辑
我猜你想问10楼我问过的东西。
因为开辟了不一样的内存地址来存储实例,而在比较时,默认==符号比较的是地址的值,而非实例里的成员的具体值。
内存地址不一样了,所以会不是同一个东西。
个人理解所写,欢迎拍砖:
[pre lang="ruby"] a = A.new
b = a
Addr Data 这是一个内存条
+---+-------+
a ---------> | 1 | 3 |-------+
+---+-------+ |
b ---------> | 2 | 3 |----+ |
+---+-------+ | |
| 3 | |<---+--+
+---| Obj1 |
| 4 | |
+---+-------+
|...| ..... |
+---+-------+
a = A.new
申请3~4的内存,吧Obj1存进去,将a赋值3
a --> Addr:1 --> Data:3 --> Addr:3 --> Obj1
b = a
b --> Addr:2 --> Data:3 --> Addr:3 --> Obj1
a和b都是3,所以
a==b # =>>true
a equal? b # =>> true
a eql? b # =>> true
==========================================================================
a = A.new
b = A.new
Addr Data 这是一个内存条
+---+-------+
a ----------> | 1 | 3 |----+ a存储的内容是3,即obj1的起始地址位
+---+-------+ | ---------------------------------------
b ----------> | 2 | 5 |----+--+ b存储的内容是5,即obj2的起始地址位
+---+-------+ | | -------------------------------------
| 3 | |<---+ |
+---+ Obj1 | | 3,4号地址位里存储的内容obj1,和
| 4 | | | 5,6号里存储的obj2一模一样。
+---+-------+ | 假设hash也一样?
| 5 | |<------+
+---+ Obj2 |
| 6 | |
+---+-------+
当使用a所代表的object时,访问顺序:
a --> Addr:1 --> Data:3 --> Addr:3 --> Data:Obj1
b --> Addr:2 --> Data:5 --> Addr:5 --> Data:Obj2
a是3,而b是5,所以
a==b #=>>false
a equal? b # =>> false
a eql? b # =>> true
=====================================================================
涉及到哈希值的比较?
a = A.new
b = a.dup
+---+--------+
a ---------> | 1 | 3 |----+
+---+--------+ |
b ---------> | 2 | 5 |----+---+
+---+--------+ | |
| 3 | Obj1 |<---+ |
+---+ hash1 | | hash1 和hash2 不一样,
| 4 | | | 除此之外,Obj1和Obj2的
+---+--------+ | 其他内容都一样?
| 5 | Obj2 |<-------+
+---+ hash2 |
| 6 | |
+---+--------+
a==b #=>>false
a equal? b =>> false
a eql? b =>> false
[/pre]
慎点……朋友学过c吗?
比如:
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- int main() {
- char *a;
- char *b;
- char c[20] = "hello world";
- a = c;
- b = c;
- //这时a,b都指向同一个地址,c
- printf("a==?b : %d\n", a == b); //1,也就是true
- //可以打印出地址的具体值
- printf("addr a = %p ;addr b = %p\n", a, b);
- //这时,a,b都指向分别申请的不同地址的开头,但它们存储的内容一模一样
- a = (char *)malloc(sizeof(char) * 20);
- memcpy(a, c, sizeof(char) * 20);
- b = (char *)malloc(sizeof(char) * 20);
- memcpy(b, c, sizeof(char) * 20);
- printf("a==?b : %d\n", a == b); //0,也就是false,比较的是地址
- //可以打印出地址的具体值
- printf("addr a = %p ; addr b = %p\n", a, b);
- printf("*a==?*b : %d\n", (*a) == (*b)); //1,也就是true,比较的是a,b指向的地址所存储的值,该值是一个char,即“h”。
- //可以打印出地址里存储的内容
- //以int打印
- printf("value(int) of a = %d ; value(int) of b = %d\n", *a, *b);
- //以ascii字符打印
- printf("value(char) of a = %c ; value(char) of b = %c\n", *a, *b);
- }
复制代码
输出:
$ ./test.exe
a==?b : 1
addr a = 000000000024FE20 ;addr b = 000000000024FE20
a==?b : 0
addr a = 0000000000571220 ; addr b = 0000000000571240
*a==?*b : 1
value(int) of a = 104 ; value(int) of b = 104
value(char) of a = h ; value(char) of b = h
|
上面这段不是对象,但能从根本解释为何两个对象的实例不能划等号。
面向对象是从面向过程抽象出来的。
把类视为结构体,
把类的成员变量视为结构体的成员值(值或者指针),该值指向一段存储具体数值的内存地址,
把类的成员函数视为结构体成员值(指针类型),指向存储某函数的内存地址。
把类的self/this关键字视为一个指针,指向本实例的地址。
【再继续下去就需要写内存存放数据的方式了……】
买一本《深入理解计算机系统》吧。
|
评分
-
查看全部评分
|