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);
我们应该能够注意到:
- 在C++当中,无论 a,b 是基本数据类型还是类对象,调用函数后,实参不会发生改变;
- 在Java当中,若a,b 是基本数据类型,则函数调用后实参不会发生改变;若a,b 是类对象,则函数调用后实参会被函数改变。
这可能是令人疑惑的事情,为什么结果不同?最直白的答案是:
对于基本数据类型,两者传递的都是数据的拷贝
对于非基本数据类型,C++是传递的是数据的拷贝,而Java传递的是数据的引用
但我们并非只满足于只知道是这样,一个很明显的问题出现了:
问题:在Java传递基本数据类型与非基本数据类型时,发生了什么?为何导致了上述不同的结果?
函数调用时发生了什么
注意:此处讨论的是func(T t)的类型,对于C++来说是传值调用。
参数传递时,为什么Java不像C++一样对非基本数据类型一样进行数据的拷贝呢?对此我们需要去了解:
- 函数调用时传递的是什么类型的参数(基本数据类型 或 类对象)?
- 函数调用时参数是如何传递的?
我们将在讨论问题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++也存在着丰富的参数传递方式,因此在将数据传递给函数时,传递给函数的可能是值、引用或地址。
- 传值调用
函数修改是形参地址内的值,形参的改变不会影响实参
void mySwap(int a, int b) {
int temp = b;
b = a;
a = temp;
}
mySwap(a, b);
//输出结果:
a:1; b:2
- 引用调用
函数修改的是实参地址内的值,实参的值被修改
void mySwap(int& a, int& b) {
int temp = b;
b = a;
a = temp;
}
mySwap(a, b);
//输出结果:
a:1; b:2
- 指针传值
函数修改的是实参地址内的值,实参的值被修改
void mySwap(int* a, int* b) {
int temp = *b;
*b = *a;
*a = temp;
}
mySwap(&a, &b);
//输出结果:
a:1; b:2
Java函数参数传递方式
Java对数据类型的处理方式不同,基本数据类型为拷贝,类对象为引用。