关于swap的几点发散思维(2)

Java到底能不能实现类似C++swap

 

C++swap函数相信大家都不陌生吧,呵呵,就是典型的三行代码。该函数位于默认的std命名空间内,并且是一个模板函数

我们这里先简单讨论下这个swap函数的参数应该是什么样。

 

首先,肯定是两个参数,我们这里命名形式参数为ab,实际参数为mn,以整数为例。如果是如下的代码:

void swap(int  a, int  b) {int temp=a; a=b; b=temp; }

调用代码如下:

int m=5,n=10;

swap(m,  n);

上面的代码是否可行呢?

只要对参数传递有一点了解的话,就知道肯定不可行。

因为C++的默认参数传递方式是传递值(Pass by value),函数体所操作的参数变量其实是实际参数的一个副本,当离开函数体的时候,这些临时变量包括参数都被销毁。那么当然不影响真正的mn

 

C时代,解决这个问题的方法是指针(Pointer)。指针可以通过一个内存地址而操作到真正的变量,而非一个副本。改进后代码如下:

void swap(int* a, int* b) {int temp = *a; *a = *b; *b = temp; }

调用代码如下:swap(&m,  &n);

这个代码是可行的。但调用比较麻烦,因为参数是两个地址,让人或多或少有点不爽。

 

理解起来并不困难。随后,C++的出现有带来了一种新的解决方案。引入了“引用”(reference)的概念。swap的代码再次变化,如下:

void swap(int& a, int& b) {int temp = a; a = b; b = temp; }

调用代码如下:swap(m,  n);

 

总之,这个swap的问题是解决了。当我首次接触到Java的时候(也就是刚开学),思考另一个问题,Java中能否实现类似swap

 

首先,有必要清楚Java的参数传递方式。Java比较特殊,它对待基本类型(比如说intchardoublebooleanlong等),按值传参;而对待非基本类型,按引用传参。

 

引用……这个对每位程序员都再熟悉不过的名词,却在一开始令我非常迷惑。

Java中,对于基本类型,我们无法改变让它变成一个指针类型或者C++的引用类型,我们只能接受Pass by value的现实。

不过非基本类型,比如说String,既然是按引用传参,实现两个String交换应该没什么问题吧。

起初,呃,我就是这么想的。但是实践后发现我错了。

就比如如下的代码:

public void swap(String a, String b)

{ String temp=a;  a=b;  b=temp; }

 

本来以为可以轻轻松松实现ab交换,结果……该方法的表现背叛了它的swap头衔。

 

为什么会这样?通过搜索,在CSDNBBS上发现了不少类似的问题,解释嘛,归结下就是Java的传递引用并不是一个深层的引用拷贝,而是一个浅层的地址拷贝,所以swap并没有操作到真正的实参

 

那么说,Java的引用和C++的引用还是有蛮大差距的咯!

 

Java的引用更大程度上是类似C++的指针,只是你完全不需要像C++那样得一个一个为指针手动解析(manual dereference)。

 

那么,我们看下面的C++代码:

void swap (int* a,int* b)

{int* temp = a; a = b; b = temp;}

 

大概,看到这里你也就明白了。Javaswap更像是上述的代码,根本没有交换ab,交换的只是指针变量的指向地址。

 

C++的引用是一种封装的常指针,这也就决定了它一旦初始化后无法修改指针自身的内容,但是可以修改指向的内容

Java的引用只是一种普通的封装指针,封装性体现在你无法让指针进行指针加减运算。这样做……当然有自己很多的好处,最大的好处就是提高了程序的安全性,但最大的弊端就是降低了程序的灵活性。

 

呵呵,关于swap就说这么多吧。

以上主要是更偏个人心得,其实swap还有一个很值得谈论的就是C++PIMPL的技巧,相关文献也是相当多。以后有机会嘛,偶会发表更多的啦!

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值