C++与Java区别浅析:函数调用

函数调用的结果差异

在C++与Java当中,我们可以看到,JAVA在调用函数时,与C++的传值调用形式相同。例如,同样调用一个函数mySwap(a,b):

//cpp模板与java泛型创建通用数据类型的方式不同,后续会对该问题进行分析
//假设通用数据类型为 T
void mySwap(T t1, T t2) {
	T temp = t2;
	t2 = t1;
	t1 = temp;
}
//函数调用
mySwap(a,b);

我们应该能够注意到:

  1. 在C++当中,无论 a,b 是基本数据类型还是类对象,调用函数后,实参不会发生改变;
  2. 在Java当中,若a,b 是基本数据类型,则函数调用后实参不会发生改变;若a,b 是类对象,则函数调用后实参会被函数改变。

这可能是令人疑惑的事情,为什么结果不同?最直白的答案是:

对于基本数据类型,两者传递的都是数据的拷贝
对于非基本数据类型,C++是传递的是数据的拷贝,而Java传递的是数据的引用


但我们并非只满足于只知道是这样,一个很明显的问题出现了:

问题:在Java传递基本数据类型与非基本数据类型时,发生了什么?为何导致了上述不同的结果?


函数调用时发生了什么

注意:此处讨论的是func(T t)的类型,对于C++来说是传值调用。

参数传递时,为什么Java不像C++一样对非基本数据类型一样进行数据的拷贝呢?对此我们需要去了解:

  1. 函数调用时传递的是什么类型的参数(基本数据类型 或 类对象)?
  2. 函数调用时参数是如何传递的?

我们将在讨论问题2时对问题1进行分类讨论。以调用函数 func(T t) 为例:

T t1; 
func(t1);

在此过程中C++与Java分别发生了什么?

1. 基本数据类型
参数传递时,C++与Java相同,毋庸置疑都是数据的拷贝,以栈上的数据为例,发生了如下过程:

int t1;
int t = t1;  //进行了值拷贝
func(t);

2. 类对象
在此之前需要了解的是:C++与Java调用拷贝构造函数的方式
为照顾不同的语言,需要声明的是:创建类对象时C++可在堆区或栈区创建,而Java只能创建在堆区,即:

1) C++
myClass mc1();  //创建在栈区
myClass* mc2 = new myClass();  //创建在堆区,返回指针,获取堆区对象需要解引用(*mc2);
2) Java
myClass mc = new myClass();  //创建在堆区,返回引用,相当于C++中的(*mc2);

(如无特殊说明,由于在栈区或堆区在此处没有影响,所以C++以创建在栈区上为例)

如何调用拷贝构造函数至关重要!!!

1) C++调用拷贝构造函数
a.方式一:
myClass mc = mc_beCopy;
b.方式二:
myClass mc(mc_beCopy);

2) Java调用拷贝构造函数
myCalss mc = new myClass(mc_beCopy);

因此,我们可以看到在C++当中 myClass mc = mc_beCopy 是拷贝构造,但在Java当中执行此语句时,mc 只是mc_beCopy的别名,相当于C++当中的 myClass& mc = mc_beCopy

而在执行func(t1)的过程中,C++和Java都默认执行如下语句:

myClass t = t1;
func(t);

也就是说,在函数调用的参数传递当中:
C++执行了类的拷贝构造函数,而Java执行的是引用!!!
至此,我们通过分析得到了上述答案。

形象点就是,你妈通过C++和Java叫你回家吃饭,C++看你在看博客挺忙就拷贝了一个你带回去了,而Java把你的真身给拎回去了!

其它

如果你是C++选手,下面的基础你已经知道。
如果你是不使用C++的Java选手,下面的内容不必知道。

C++函数中不同的参数传递方式

由于C++引用与指针的存在,C++也存在着丰富的参数传递方式,因此在将数据传递给函数时,传递给函数的可能是值、引用或地址。

  1. 传值调用
    函数修改是形参地址内的值,形参的改变不会影响实参
void mySwap(int a, int b) {
	int temp = b;
	b = a;
	a = temp;
}
mySwap(a, b);

//输出结果:
a:1; b:2
  1. 引用调用
    函数修改的是实参地址内的值,实参的值被修改
void mySwap(int& a, int& b) {
	int temp = b;
	b = a;
	a = temp;
}

mySwap(a, b);

//输出结果:
a:1; b:2
  1. 指针传值
    函数修改的是实参地址内的值,实参的值被修改
void mySwap(int* a, int* b) {
	int temp = *b;
	*b = *a;
	*a = temp;
}

mySwap(&a, &b);

//输出结果:
a:1; b:2

Java函数参数传递方式

Java对数据类型的处理方式不同,基本数据类型为拷贝,类对象为引用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值