C++与java中的参数传递

  Java传值与传引用。对基本数据类型传递值,对象则传引用。传递对象时,若在被调函数体内改变了对象的值,那么在调用函数内对象的值也会改变。试试下面一段代码。

void  testValue( int  i)
    
{
        i
=100;
    }

    
void  testInteger(Integer i)
    
{
        i
=new Integer(200);
    }

    
void  testStr1(StringBuffer str)
    
{
        str.append(
"---add--");
    }

    
void  testStr2(StringBuffer str)
    
{
        str
=new StringBuffer("@new@");
    }

    
public   static   void  main(String[] args)
    
{
        
new TestDerived().test();
    }

    
void  test()
    
{
        
int i=7;
        
        System.out.println(
"i:"+i);
        testValue(i);
//传值
        System.out.println("testValue(i):"+i);
        
        Integer oi
=new Integer(7);
        testInteger(oi);
//传引用
        System.out.println("testInteger(i):"+oi);
        
        StringBuffer str
=new StringBuffer("raw");
        System.out.println(
"str:"+str);
        testStr1(str);
//传引用
        System.out.println("testStr1(str):"+str);
        
        testStr2(str);
//传引用
        System.out.println("testStr2(str):"+str);
    }

如果按照我的理解,那么结果应该是:
i:7
testValue(i):7
testInteger(i):200
str:raw
testStr1(str):raw---add--
testStr2(str):@new@


可是实际上,运行出来的结果却是:
i:7
testValue(i):7
testInteger(i):7
str:raw
testStr1(str):raw---add--
testStr2(str):raw---add--

    让我很困惑。查阅了一些资料,才发现,引用和指针一样,在编译器传递参数值,都会为这个引用/指针制作一个副本。比如上面的函数void testInteger(Integer i);当调用testInteger(oi)时,编译器为引用oi制作一个副本_oi,这个副本_oi当然也指向对象oi指向的对象。 当在函数体内执行i=new Integer(200);时,创建了一个Integer对象,并将其引用赋值给_oi。而在函数main内的对象oi却并没有改变。因而输出的值仍然为7。而为社么函数testStr1会改变字符串str的值呢?那是因为testStr1的执行语句,str.append("---add--");是针对str指向的对象操作的,因此也改变了函数main内字符串str的值。

    极端一点说,java里面都传的是值,即在函数调用时,都会为参数制作一个副本,然后将参数值复制过去。
只不过,对基本数据类型参数,传递的是该参数的基本数据值,在函数内创建的是相同数据类型的副本;而对对象而言,传递的是引用的值,会创建一个引用的副本,然后使其指向引用参数所指向的对象。当传递参数为对象时(即传引用),在被调函数体内,如果是针对引用所指向的对象操作,那么将会修改调用函数内对象的值;如果针对引用本身操作,那么,将不会修改调用函数内对象的值。就像上面的例子,testStr1是针对引用所指向的对象操作(改变调用者的值),而testStr2则是针对引用本身操作(不改变调用者的值)。


C++中的指针与引用也与这个是非常类似的。


void  testValue( int  i)
{
    i
=100;
}

void  testPoint1( int *  pi)
{
    pi
=NULL;
}

void  testPoint2( int *  pi)
{
    
*pi=200;
}

void  testReference( int   * pi)
{
    pi
=NULL;
}

int  main( int  argc,  char *  argv[])
{
    
int* pi=new int(7);
    cout
<<"*pi:"<<*pi<<endl;
    testValue(
*pi);
    cout
<<"testValue(pi):"<<*pi<<endl;

    testPoint1(pi);
    cout
<<"testPoint1(pi):"<<*pi<<endl;//correct

    testPoint2(pi);
    cout
<<"testPoint2(pi):"<<*pi<<endl;

    
int *&rp=pi;
    testReference(rp);
    cout
<<"testReference(pi):"<<*pi<<endl;//correct
    
    
return 0;
}


运行结果为:
*pi:7
testValue(pi):7
testPoint1(pi):7(由于是针对指针本身操作,即使函数体内指针被赋值为null,这里也不会出错)
testPoint2(pi):200
testReference(pi):200 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值