引用和址传递是有些不同的,这里只取相同的部分---不要被误导。
假设class A,class B分别是C++和java的类。
C++
A的对象生成方法:
1)A x; //调用构造函数生成x。后面还可以 x = y,调用拷贝构造函数,可能是值传递,也可能是部分引用,取决于class A是否重载“=”。
2)A x = A(..); //error,没有这种定义方式,只有A* x =new A(..);
3)A x(); //error,不能这么写---和定义一个函数,返回值类型是A混淆。但可以A x(y)。
PS. 对象y值传递给x,两种方法:
1.A x = y,调用拷贝构造函数A(A& a)(小心若A(A& a)实现不同,则可能变成指针传递---例如A中的成员是指针时);
2.A x(y),调用拷贝构造函数A(A& a)---这里的引用符号不可以省略,表示不是参数赋值,即传递参数时不产生新的对象。(小心若A(A& a)实现不同,则可能变成指针传递);
A x = y等价于A x(y)。拷贝构造函数可以调用系统默认的--成员变量直接相等赋值,或重写覆盖。
A x = y不等价于A x ;x= y。后者调用重载操作符"=",可以调用系统默认的--成员变量直接相等赋值,或重写覆盖。
#include "iostream"
using namespace std;
class CA{
public:
int* l;
int* j;
public:
CA(){
cout<<"hello"<<endl;
l = new int(1);
j = new int(2);
}
CA(int a, int b){
cout<<"world"<<endl;
//l = &a;
l = new int(a);
j = new int(b);
}
~CA(){
if(l!=NULL)delete l;
delete j;
}
};
int main(){
CA a1(1,2);
CA a2 = a1;//调用的是系统默认的CA a2(a1);
*a2.l = 11;
cout<<*a1.l<<endl;
cout<<*a2.l<<endl;
*a1.j = 22;
cout<<*a1.j<<endl;
cout<<*a2.j<<endl;
//~a1();//析构函数不能自己调用
return 0;
}
#include "iostream"
using namespace std;
class CA{
public:
int l;
int j;
public:
CA(){
cout<<"hello"<<endl;
l = 1;
j = 2;
}
CA(int a, int b){
cout<<"world"<<endl;
l = a;
j = b;
}
//拷贝构造函数,copy的原因是l = b.l,也有默认的
CA(CA& b)//参数引用,避免复制对象的过程
{
cout<<"拷贝构造函数"<<endl;
l = b.l;
j = b.j;
}
};
int main(){
CA a1(1,2);
CA a3;
a3 = a1;
cout<<a3.l<<endl;
cout<<a3.j<<endl;
CA a4=a1;
CA a5(a1);
return 0;
}
Java
B的对象生成方法:
PS. 在java中两类型:引用类型(class)和原始(基础)类型(int)以及String等。
引用类型都是址传递,原始(基础)类型都是值传递。
1)B x = new B(); //B x; 等价于B x=null;
2)B x = y; //引用
3)B x ; B = y; //不同于A x;就可以生成对象了。---------引用。
PS. 1. Java中没有重载操作符; 2. Java中对象间复制,而不是引用,可以定义一个函数 B copyfrom( B Y){ B new; 成员一个一个复制;return new; }-----其它方法就不详解了。见http://www.blogjava.net/JAVA-HE/archive/2008/04/28/196727.html。
String 和 StringBuffer等核心也是一样的,但使用不同。见http://blog.csdn.net/yirentianran/article/details/2871417。
对于JAVA传值和传引用,JAVA程序员面试宝典中有详细解释。
总之,对于基本类型变量,JAVA和C/C++是一致的,传值;
对于对象型变量,JAVA传引用的副本。传引用的副本的实质就是复制指向地址的指针。
java中void func(JA a)类似于C++中的void func(CA* a),而不是C++中的void func(CA& a)。
C++中,传递的参数是引用类型时,传递的是真实引用(别名),而不是引用副本(没有引用副本的概念)。
而C++中,即使是A x(y) 或 A x; x=y 或 void func(A x) 或A func(...){... return x},没有使用*、&,也需要注意
1、是否重写操作符=(或拷贝构造函数),若没有重写,则传值,若重写,则可能类似于传引用(重写操作符=(或拷贝构造函数)实现中,复制指针,共享内存);
2、A x = y不等价于A x ;x= y。前者调用拷贝构造函数,后者调用重载操作符"="。所以取决于你用哪种方式传递。
拷贝构造函数用途: 用一个对象初始化另一个对象要调用拷贝构造函数 对象作为参数值传递的时候要调用拷贝构造函数 函数返回一个对象要调用拷贝构造函数 重写拷贝构造函数时,如果不使用引用,调用拷贝构造函数的时候涉及到值传递,实参初始化形参要调用拷贝构造函数,这样就会造成递归调用。CA(CA& b)