c++ 指针与引用(别名)的区别,c++引用与java引用区别

c++ 指针p是一个独立的变量,存的别的变量a的地址(有两个存储空间,p 和a)

c++引用(别名)b是另个一个变量a的别名,是同一个变量。(只有一个存储空间b a表示同一个空间)

 

java 引用就是c++的指针,只是不能++,--。

 

最近写一个Java String函数的时候遇到引用原理上的一些问题,当时很急,没有仔细思考,最后通过返回值回避了引用的使用。

今天早上上班的路上,突然就想起了当时使用python的时候,同样存在的引用问题,和c++对比后,发现其实问题并没有那么简单。

在《java编程思想》里有对javac++引用的区别的介绍,现在想起来,书的中文翻译对这段的解释并不专业,没有把问题的本质讲清楚。

 

java的引用和python很像,但无论是原理上,还是使用上,都完全不同于c++的引用。

Java中的引用在使用上非常类似于c++的指针,相当于通过一个变量存储实际对象的地址,如下例:

A a = new A(1);

A b = a;

 

 

如上图,ab作为A(1)的引用,相当于c++中的指针,它们都存储了A(1)的地址。在函数调用时

fun(A x)

{

   

}

 

当我们调用fun(a)时,实际上相当于执行了 x = a;

也就是说,现在

 

 

 

 

我们知道java里函数是按值传递的,fun调用时把a的值(A(1)的地址)传递给了x。如果我们通过x更改了A(1),那么所有指向A(1)的引用在使用新的A(1)时都会收到影响,但是,如果在

fun(A x)

{

         x = new A(3);

}

x 被重新赋值,那么对ab以及它原来指向的A(1)没有任何影响。

 

下面来说c++里的引用,在c++里面,使用引用这个词其实并不恰当,因为c++里的引用其实是一个变量的别名,也就是说

A a = A();

A& b = a;

这个时候b就是a,只不过换了一个名字而已,b是依托于a而存在的,换句话说,一个人有名字,同时起了一个别名,但是有别名的前提是他必须要有名字,因此,c++不存在空引用。

同样用一个函数来说明:

fun(A& x)

{

         x = A(3);

}

 

我们调用fun(a)时,相当于A& x = a;那么在fun的作用域内,x就是a。所有对x的改变就是对a的改变。

也就是说,c++里的引用其实是扩展了a的作用域,我们知道c++中函数也是按值传递的,所以引用这样的操作是依靠指针实现的,调用fun(a)时相当于

A*  tmp_x = &a;

x 等价于(*tmp_x)。在fun内部所有使用x的地方都被替换为了*tmp_x

 

那么,有没有可能在java中实现c++中引用的效果呢?

如果想完全达到c++中引种的效果是不可能的,但是,可以通过一些包装来完成:

比如我们可以借助数组来实现,将原来的a包裹在一个数组内传递进去,我们可以更改fun的定义为:

fun(A[] x)

{

}

那么我们调用fun时,fun(new A[] {a})就可以了……

 

注:这里是错了,数组A[0]的位置存储的是a的值,因此对A[0]的改变不会影响a.......昨天脑残了.....所以这种方法是没有意义的,想达到c++的引用效果,在java里的应用层面基本是不可能的,必须从编译层面借助内存地址来实现...

 

python中的引用和java里的引用很类似,因此不做赘述。

 

java里还有一个问题,当变量类型为基本类型时,不像python一样存在指向常量的引用,而是和c++一样直接在栈上存储数据。这个主要是历史原因造成的,java当年为了兼容c++的部分语法而使得基本类型和c++中的基本类型类似,也就是说java不是完全的面向对象语言,intfloat等并不是对象……..

类似于这样的问题还有java中的泛型,为了兼容以前版本的代码使得泛型不得不通过擦除机制来实现,和c++的泛型比起来完全是形似而神不似。

 

鉴于以上种种,不得不非常佩服python3.0版本中表现出的壮士断腕般的勇气…….

 

执着于过去只会让未来的路越走越窄………

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值