类引用机制

      在C++和Java中都存在类引用,C++中是要明确指出的,显性的;而Java中是隐形的。

      在C++中,"T &b=a;" 说明b是a的引用,两者是同名,指的同一个东西。而非指针的类声明,就同时创建了一个类,如"T a;"实际上a已经实例化了。而声明类引用时不需要创建新对象,而是直接指向原来的对象。

     类引用在函数的形参和返回值中起到很大的作用。默认的类参数,是通过复制函数(重载=运算符),复制入参一个新对象给函数体。函数中如果修改形参,不会对入参有影响。如果返回值也是类,那么也会通过复制函数,构造一个新对象返回给调用者。

     如果形参采用类引用,那么函数将直接引用原有的入参,此时修改形参就会修改真实的入参。返回值是类引用时,将不再使用复制函数,而是直接将对象返回给调用者。如果返回的对象是局部变量,那么采用引用返回就会出错。

      在Java中,类实例声明和构造是分开。"T a;"是声明,而"a=new T();"才是构造。引用声明和C++相同。但是Java的机制与C++不同,Java中的引用也叫句柄,或者说句柄才是其真实名称。类声明的都是一个句柄,调用构造函数才会使得句柄指向类实例。因此Java中没有类似于C++中的复制函数,因为Java的复制都是直接复制句柄内容。例如"T b=a;"只不过是将a的句柄复制(赋值)给了b,从而b也指向a指向的类实例。可以看出Java与C++在此处的不同,Java依然只有一个实例,而C++则存在了两个实例。

      所以在函数中,Java的形参都是入参的句柄复制,并且是浅复制(只复制该句柄,而不复制句柄指向的下一层句柄)。因此在函数中,直接修改形参是不能改变入参的。但是如果修改形参指向的对象的下一层句柄则会修改入参。因此在Java中不存在像C/C++中一样的Swap函数。函数的返回值,也是句柄复制。如果在函数中构造一个局部变量类实例,那么是可以返回到外部的,当然那个局部变量的句柄是不存在了。

      Java中要复制对象,需要重载clone函数,并且要分清是浅复制还是深复制(完全构造一个新对象,两者的内部数据和实例不存在重叠)。

ExpandedBlockStart.gif ContractedBlock.gif class  A
private
    
int num;
public:
ExpandedSubBlockStart.gifContractedSubBlock.gif    A(
int i=0):num(i){ cout<<"create"<<endl; }
ExpandedSubBlockStart.gifContractedSubBlock.gif    
~A(){ cout<<"delete num = "<<num<<endl; }
ExpandedSubBlockStart.gifContractedSubBlock.gif    A(A
& a){cout<<"copy"<<endl;num=a.num;};//复制构造函数
    A& operator=(A &a)//赋值构造函数
ExpandedSubBlockStart.gifContractedSubBlock.gif
    {
        cout
<<"assign"<<endl;
        num 
= a.num;
        
return *this;
    }

}
;
A function1(A a)  
ExpandedBlockStart.gifContractedBlock.gif
{
    cout
<<"function 1\n";
    
return a;
}


A function2(A 
& a)  
ExpandedBlockStart.gifContractedBlock.gif
{
    cout
<<"function 2\n";
    
return a;
}


A
&  function3(A  & a)  
ExpandedBlockStart.gifContractedBlock.gif
{
    cout
<<"function 3\n";
    
return a;
}


void  main()
ExpandedBlockStart.gifContractedBlock.gif
{ A a(11);
  A b
=a;
  A c;
  c
=a;
  cout
<<"------------------------\n";
  function1(a);
  cout
<<"------------------------\n";
  function2(a);
  cout
<<"------------------------\n";
  function3(a);
  cout
<<"------------------------\n";
  cout
<<"ok"<<endl;
}


ExpandedBlockStart.gifContractedBlock.gif
/**/ /************* out ********************
create
copy
create
assign
------------------------
copy
function 1
copy
delete num = 11
delete num = 11
------------------------
function 2
copy
delete num = 11
------------------------
function 3
------------------------
ok
delete num = 11
delete num = 11
delete num = 11
****************************************
*/

 

转载于:https://www.cnblogs.com/xiaoyz/archive/2009/04/07/1430702.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值