LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: quanliking

c/c++ 中的传值调用和传引用,我的理解.

[复制链接]
 楼主| 发表于 2003-7-30 14:48:26 | 显示全部楼层
最初由 Eelkel 发表
不错。

传引用只有在传递对象时才有优势,引用本身也需要4个字节的空间,和int是一样的,所以传int是不应该使用引用的。


真是太好了!兄弟说到我心里去了。
其实我举这个例子目的,也就是为了搞清 c++ 在处理引用时具体做了哪些动作?

以下是我的问题,表达上可能有不清楚的地方:

1、引用参数 x 和 被引用对象 i 究竟是什么关系?

2、在调用函数 f() 时,是否需要为 x 分配空间(或临时空间)?有的话放在哪个位置?

对于 "引用本身也需要 4 个字节的空间" 我不太理解.希望能具体说明.

3.引用 kj501 的话(准确地说,这里应该讲 copy):
"引用实际上是一个常量指针,不会再指向别的对象。..."

照这样理解,引用该是一个特殊的指针,是否就可以用指针来理解了?
先来看个传递指针的例子:

  1. //: PassByPointer.cpp
  2. #include <iostream>
  3. using namespace std;

  4. void f(int* p) {
  5.     cout << "p = " << p << endl;
  6.     cout << "*p = " << *p << endl;
  7.     cout << "&p = " << &p << endl;
  8.     cout << "size of p = " << sizeof(p) << " Byte" << endl;
  9.     // Define a new variable
  10.     int y = 150;
  11.     cout << "y = " << y << endl;
  12.     cout << "&y = " << &y << endl;
  13.     // Point to new value
  14.     p = &y;
  15.     cout << "p = " << p << endl;
  16.     cout << "*p = " << *p << endl;
  17.     cout << "&p = " << &p << endl;
  18.     cout << "size of p = " << sizeof(p) << " Byte" << endl;
  19. }

  20. int main() {
  21.     int x = 47;
  22.     cout << "x = " << x << endl;
  23.     cout << "&x = " << &x << endl;
  24.     f(&x);
  25. }   
复制代码


屏幕输出:
x = 47
&x = 0x22ff6c
p = 0x22ff6c
*p = 47
&p = 0x22ff50
size of p = 4 Byte
y = 150
&y = 0x22ff44
p = 0x22ff44
*p = 150
&p = 0x22ff50
size of p = 4 Byte

可以看到指针也是一个变量,这里c++ 为这个整数指针分配了 4 Byte 的空间,有独立的地址,可以重新指向其它变量.

如果引用是常量指针的话(姑且允许我称之为"引用指针"),那么在哪个地方保存了它的地址呢?
按这个思路,显然无法用 &x 来得到,这样得到的是它所引用对象的地址.
这里 C++ 是否对我们做了隐瞒,由于我们没法得到这个引用指针地址,所以就无法修改里面的值以让他指向新的变量.从而有常数指针的说法?

假如我想得到这个引用指针的地址,有办法吗?

请允许我犯新手的一些常见错误,表达上和理解上的一些误区,望能不留情面指出来,也希望 c++ 玩家尽可能具体的用比较容易理解的语言或一些生动的实例来传业授道解惑,对一些专业术语,能做一些简单的解释,并提供一些良好的忠告和编程习惯,在此先谢谢热心的朋友,为你们不吝惜业余时间对论坛的无私奉献感动,我为你们骄傲.
发表于 2003-7-30 15:32:31 | 显示全部楼层
引用需要保存它所引用的对象的地址。在32位中,地址占32位,就是4个字节。所以"引用实际上是一个常量指针”。
发表于 2003-7-31 03:04:48 | 显示全部楼层
利用指针进行 pass by reference 的 C 程序:

  1. /**********************************************************************
  2. *                                                                    *
  3. *  reference.c:                                                      *
  4. *      Indicate the difference between passing by value and passing  *
  5. *      by reference.                                                 *
  6. *                                                                    *
  7. * ------------------------------------------------------------------ *
  8. *                                                                    *
  9. *  This program is released to public domain.  It is a rewriting in  *
  10. *  C of an C++ example by [email]quanli@linuxfire.com[/email].                      *
  11. *                                                                    *
  12. **********************************************************************/
  13. #include <stdio.h>

  14. void modify(int *, int);

  15. int main(void)
  16. {
  17.     int i = 0;
  18.     int j = 0;
  19.     printf("In function main():\n");
  20.     printf("i = %d, j = %d.\n", i, j);
  21.     printf("&i = %p, &j = %p.\n", &i, &j);
  22.     modify(&i, j);
  23.     printf("Back to function main():\n");
  24.     printf("i = %d, j = %d.\n", i, j);
  25.     return 0;
  26. }

  27. void modify(int *x, int y)
  28. {
  29.     printf("Enter function modify().\n");
  30.     printf("In function modify():\n");
  31.     printf("*x = %d, y = %d.\n", *x, y);
  32.     printf("x = %p, &y = %p.\n", x, &y);
  33.     *x += 1;
  34.     y += 1;
  35.     printf("*x = %d, y = %d.\n", *x, y);
  36.     printf("Exit function modify().\n");
  37.     return;
  38. }
复制代码
发表于 2003-7-31 09:04:02 | 显示全部楼层
我的说法可能不太准确,引用可以被想像为一个常量指针,作出这种理解不会有任何问题。但引用并不是一个对象,也不能像指针那样去操作。在一些情况下,编译器可以通过优化去掉引用,使用在执行时,根本不存在任何表示引用的东西。
引用的主要用途是为了描述函数参数和返回值,特别是为了运算符重载。在这种情况下,用指针容易出问题,用引用会安全一些。
发表于 2003-7-31 20:57:36 | 显示全部楼层
最初由 pupilzeng 发表
请问一下什么叫对象切片问题?从来没有听过。


我觉得对象切版问题并不是很重要

因为你传进去的是什么对象的指针
那么就可以使用多少接口

传引用也一样
如果函数定义的是父类的引用
那么你能使用的也只是父类的接口

而不会能用到子类接口

大家继续讨论
发表于 2003-7-31 22:34:37 | 显示全部楼层
如果使用指针或引用作为参数,就不会存在对象切片问题。实际上大多数的函数参数都是引用,只是在用值传递参数时,要注意这个问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表