c++与java区别的理解(一)--引用

在刚刚接触java的引用的时候,我便不假思索的将它等同于c++的引用,后来在实践中发现,和我想的有很大的不同。

       先来看看两者之间的定义:

       java中的引用:“每种编程语言都有自己的数据处理方式。有些时候,程序员必须注意将要处理的数据是什么类型。你是直接操纵元素,还是用某种基于特殊语法的间接表示(例如C/C++里的指针)来操作对象。所有这些在 Java 里都得到了简化,一切都被视为对象。因此,我们可采用一种统一的语法。尽管将一切都“看作”对象,但操纵的标识符实际是指向一个对象的“引用”(reference)。”这是java编程思想的原话。

      c++中的引用:引用是已定义的变量的别名。

     初看两者定义,我们或许看不出什么,但先从它们之间的创建声明讲起:

[java]  view plain  copy
 print ?
  1. A a=new A();  
      对于Java而言,在这里命名了A类的引用a,用来指向A类的对象,不妨将它与指针来做下比较:

[cpp]  view plain  copy
 print ?
  1. int *a=new int[10];  
     你会发现命名的规则很相似,再来看看Java的引用和c的指针是如何存储的:

     对于Java引用:先在栈中存对象的引用,也就是本例的a,再向堆中申请内存空间来存该类的对象(new A()),然后a指向对象所在的内存。

     对于c++的指针:先在栈中存指针a,再向堆中申请内存空间存该指针所指向的元素,然后a指向该地址。

     两者在内存中的操作可谓说是一模一样的,其实,java的引用在本质上就是一个指针,只不过对指针进行了封装,使其不能直接对内存进行操作,java的引用也只能指向对象,而不能指向基本数据类型。下面通过一个简单的代码来加深对Java引用的理解:

[java]  view plain  copy
 print ?
  1. class A{  
  2.     private int a;  
  3.     public A(int a){  
  4.         this.a=a;  
  5.     }  
  6.     public String toString(){  
  7.         return a+"";  
  8.     }  
  9. }  
  10. public class test {  
  11. public static void main(String args[]){  
  12.     A a=new A(1);  
  13.     A b=new A(2);  
  14.     System.out.println(a+" "+b);  
  15.     swap(a,b);  
  16.     System.out.println(a+" "+b);  
  17. }  
  18. public static void swap(A a,A b){  
  19.     A temp;  
  20.     temp=a;  
  21.     a=b;  
  22.     b=temp;  
  23. }  
  24. }  

   

        运行这份代码,得到的结果是一模一样的,也就是说,没有交换成功,究其原因,与传递指针一样,只交换了指针而没有交换地址是一样的道理,引用和指针一样,传递进去的是它的副本,交换的是它们的副本而本身没有被交换。谈到这,我们可以这么想,不管是java的引用或者是c/c++的指针,抑或者是两者的基本数据类型,传递进方法/函数的值只是它们的副本,即是它们的一份拷贝,自身没有被传递进去。而事实上,也的确是这样的,《java编程思想》有这么一段话:“java所支持的“按址传递’是完全错误的”,因为java对象标识符实际上是”对象引用“。并且他还说(指编程思想作者所引用这段话的作者)任何事物都是按值传递的”。怎么理解这段话呢?我们可以将c指针,java的引用看作是一种值,一种特殊的值,然后将该值的拷贝传进了函数或方法,而我们讲的c/c++中按地址传递,其实就是一种特殊的值传递而已。但是。c++的引用却不这么做:

        在上文中提到,c++的引用是已定义变量的别称。这怎么理解呢?声明一个变量,包括变量类型和变量名,而变量名也就代表着这个变量,而c++的引用是这个变量的别名,是这个变量的另一个名字。上文所说c++引用不遵照值传递的规则是因为,传递进去的是值的本身,而不是值的拷贝,在 C++ 中当传递给函数的参数是引用时,您传递的就是这个引用,或者内存地址。用c++来实现上述代码:

[cpp]  view plain  copy
 print ?
  1. #include<iostream>  
  2. using namespace std;  
  3. class A  
  4. {  
  5. private :  
  6.     int a;  
  7. public :  
  8.     A(){}  
  9.     A(int a)  
  10.     {  
  11.         this->a = a;  
  12.     }  
  13.     friend ostream& operator<<(ostream &os, A test)  
  14.     {  
  15.         os << test.a;  
  16.         return os;  
  17.     }  
  18. };  
  19. void swap(A &a, A &b)  
  20. {  
  21.     A temp;  
  22.     temp = a;  
  23.     a = b;  
  24.     b = temp;  
  25. }  
  26. int main()  
  27. {  
  28.     A a(1);  
  29.     A b(2);  
  30.     A &test1 = a;  
  31.     A &test2 = b;  
  32.     cout << a << " " << b << endl;  
  33.     swap(test1, test2);  
  34.     cout << a << " " << b << endl;  
  35.     system("pause");  
  36.     return 0;  
  37. }  


可见,交换成功。而且c++的引用本质上也是一个指针,是一个指针常量,即const指针。

     总结一下,就语言机制来说,java的引用是用来管理和命名对象,而C++的引用机制是很纯粹的,就是别名而已。java引用在语法上更像c++的引用,而其实质上就是c/c++的指针。

原文:http://blog.csdn.net/hackersuye/article/details/78875119

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值