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

2020-09-29 17:15发布

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

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

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

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

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

A a=new A();

     对于Java而言,在这里命名了A类的引用a,用来指向A类的对象,不妨将它与指针来做下比较:

int *a=new int[10];

    你会发现命名的规则很相似,再来看看Java的引用和c的指针是如何存储的:

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

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

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

  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++来实现上述代码:

  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++的指针。

作者:suye233

链接:https://blog.csdn.net/hackersuye/article/details/78875119

来源:CSDN
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。