中国青基会
RSS
热门关键字:  None  linux+moodle安装  mac  rhel5  199
当前位置 : Nixsky>程序设计>c/c++>列表

C++的引用的传递和返回兼批判

来源: 作者: 时间:2007-05-19 点击:


C中只有传值(PV)和传地址(PP)。有些语言仅仅有传地址,没有传值。好象FORTRAN就是。
实际上从汇编开始理解,传递(包括参数和返回)要么是PV要么是PP。那么引用是什么东西?

引用是C++不得以产生的概念。如果没有C的PV,如FORTRAN那样全是引用(一种PP),也就不会出现引用的概念。

下面的小程序和对应的汇编可以说明引用本质是什么。

从func0和func1的调用可以看出引用本质就是地址传递(PP)。2个函数调用的汇编一样的。
func2返回引用,实际是返回地址,也是地址传递(PP)

那么引用有好处吗?我个人意见,不多。除非万不得已非用不可,建议千万不要使用。
使用了,后果是让简单的程序无法读懂(不是因为引用概念复杂),尤其是分模块的情况下。
比如:
int i = 1;
return i;
的本意很清楚,可以有引用的情况下,这2行的意义是不确定的。比如往前看才能确定。
function(i); 也是一样,本来清楚的东西变为不确定。

实际上引用就是PP,但是一种用编译器做了伪装的PP。因此使程序更不容易读。

欢迎批评和讨论。

CODE:
#include <stdio.h>
int func0(int &i)
{
   i++;
   return 100;
}
int func1(int *ip)
{
    (*ip) ++;
   return 101;
}
int& func2(int i)
{
static int ii = 123;
    return ii;
}

main()
{
int i, j;

    i = 4;
    j = 104;
    j = func0(i);
    //printf("i = %d j = %d\n", i, j);
    j = func1(&i);
    //printf("i = %d j = %d\n", i, j);
    j = func2(9);
    //printf("i = %d j = %d\n", i, j);
}

   .file   "t2.c"
        .text
        .align 2
.globl _Z5func0Ri
        .type   _Z5func0Ri,@function
_Z5func0Ri:
.LFB2:
        pushl   %ebp
.LCFI0:
        movl    %esp, %ebp
.LCFI1:
        movl    8(%ebp), %eax
        incl    (%eax)
        movl    $100, %eax
        leave
        ret
.LFE2:
.Lfe1:
        .size   _Z5func0Ri,.Lfe1-_Z5func0Ri
        .align 2
.globl _Z5func1Pi
        .type   _Z5func1Pi,@function
_Z5func1Pi:
.LFB4:
        pushl   %ebp
.LCFI2:
        movl    %esp, %ebp
.LCFI3:
        movl    8(%ebp), %eax
        incl    (%eax)
        movl    $101, %eax
        leave
        ret
.LFE4:
.Lfe2:
        .size   _Z5func1Pi,.Lfe2-_Z5func1Pi
        .align 2
.globl _Z5func2i
        .type   _Z5func2i,@function
_Z5func2i:
.LFB6:
        pushl   %ebp
.LCFI4:
        movl    %esp, %ebp
.LCFI5:
        subl    $4, %esp
.LCFI6:
        movl    $123, -4(%ebp)
        leal    -4(%ebp), %eax
        leave
        ret
.LFE6:
.Lfe3:
        .size   _Z5func2i,.Lfe3-_Z5func2i
        .align 2
.globl main
        .type   main,@function
main:
.LFB8:
        pushl   %ebp
.LCFI7:
        movl    %esp, %ebp
.LCFI8:
        subl    $8, %esp
.LCFI9:
        andl    $-16, %esp
        movl    $0, %eax
        subl    %eax, %esp
        movl    $4, -4(%ebp)
        movl    $104, -8(%ebp)
        subl    $12, %esp
        leal    -4(%ebp), %eax
        pushl   %eax
.LCFI10:
        call    _Z5func0Ri
        addl    $16, %esp
        movl    %eax, -8(%ebp)
        subl    $12, %esp
        leal    -4(%ebp), %eax
        pushl   %eax
        call    _Z5func1Pi
        addl    $16, %esp
        movl    %eax, -8(%ebp)
        subl    $12, %esp
        pushl   $9
        call    _Z5func2i
        addl    $16, %esp
        movl    (%eax), %eax
        movl    %eax, -8(%ebp)
        movl    $0, %eax
        leave
        ret
.LFE8:
.Lfe4:
        .size   main,.Lfe4-main
        .ident  "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"
最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册