易码技术论坛

 找回密码
 加入易码
搜索
查看: 1396|回复: 12

[源码] [求助]关于引用

[复制链接]
发表于 2007-12-3 13:05:08 | 显示全部楼层 |阅读模式
在C++中,b是一个类:
void a(string b){}

void a(string &b){}
一样么?
还有:
string a(){string b;return b;}

string &a(){string b;return b;}
一样么?为什么啊?
发表于 2007-12-3 14:05:43 | 显示全部楼层
原帖由 yan 于 2007-12-3 13:05 发表
在C++中,b是一个类:
void a(string b){}

void a(string &b){}
一样么?

不一样。
void a(string b){}
在方法内部得到是参数的一个拷贝。
void a(string &b){}
方法内部的 b与传进去的是同一个对象。


原帖由 yan 于 2007-12-3 13:05 发表
还有:
string a(){string b;return b;}

string &a(){string b;return b;}
一样么?为什么啊?

string &a(){string b;return b;}
这个是错的。。
b只是一个方法内部的临时变量。
发表于 2007-12-3 14:08:20 | 显示全部楼层
至于为什么。。
偶可能知道,也可能不知道,但肯定是讲不清楚了:-)
发表于 2007-12-3 14:17:09 | 显示全部楼层
不过基本上,在函数参数这里,
可以把引用看成使用指针的一个快捷方式。
发表于 2007-12-3 14:30:44 | 显示全部楼层
参数可以有入参(in)和出参(out)。

一般一个函数的执行结果是一个int, float, char等原子级数据类型可以直接返回,如果是比较复杂的结构可以返回一个指针。但这些都有一个问题就在于只能返回"一个"结果。
比如你想写一个swap方法交换a、b两个数,明显用return的方式就不适合。所以就可能用到出参。

其实出参原理很简单就是把a、b的地址发给函数,函数直接修改在该函数之外的a、b变量。所以swap的形式可能是void swap(int *pa, int *pb)。而你在函数内部需要用*解引用才能访问a、b:*pa = xxx......

引用其实和他是同一道理,不过在语法上更为直观,如果用引用的话函数的原型就是void swap(int &ra, int&rb)。而在函数内部则可以直接用ra、rb操纵传进来的参数,而不用再用地址去解析一遍。

其实你可以简单的引用看成解析过的指针
 楼主| 发表于 2007-12-3 22:00:56 | 显示全部楼层
但是这个有怎么解释?
  1. #include <stdio.h>

  2. class A
  3. {
  4. public:
  5.         char *p;
  6.         char q;
  7. public:
  8.         A()
  9.         {
  10.                 p = 0;
  11.                 printf("AAAA\n");
  12.         }
  13.         ~A()
  14.         {
  15.                 //if (p)
  16.                 //{
  17.                 //        delete p;
  18.                 //        p = 0;
  19.                 //}
  20.                 printf("~AAAA\n");
  21.         }
  22. };

  23. void a(A b)
  24. {
  25.         *b.p = 56;
  26.         b.q = 23;
  27.        
  28. }

  29. void c(A &d)
  30. {
  31.         *d.p = 90;
  32.         d.q = 34;
  33. }

  34. int main(int argc, int *argv[])
  35. {
  36.         A i;

  37.         i.p = new char(2);
  38.         i.q = 50;

  39.         printf("%d %d\n", *i.p,i.q);
  40.         a(i);
  41.         printf("%d %d\n", *i.p,i.q);
  42.         c(i);
  43.         printf("%d %d\n", *i.p,i.q);
  44.         return 0;
  45. }
  46. /*
  47. *出现:AAAA
  48. *      2 50
  49. *      ~AAAA
  50. *      56 50
  51. *      90 34
  52. *      ~AAAA
  53. */
复制代码

[ 本帖最后由 yan 于 2007-12-3 22:04 编辑 ]
发表于 2007-12-3 23:27:36 | 显示全部楼层
注意class A中的p是个指针就OK了
发表于 2007-12-4 00:12:07 | 显示全部楼层
  1. A i           AAAA
  2. printf()      2 50
  3. a(i)          ~AAAA    原形a(A b),把i作为入参时调用的是拷贝构造函数,
  4.                        拷贝构造函数形如A::A(const A& in),
  5.                        所以只有在函数最后销毁入参时产生了~AAAA
  6. printf()      56 50
  7. c(i)          无
  8. printf()      90 34
  9.               ~AAAA    销毁i
复制代码
 楼主| 发表于 2007-12-4 10:33:57 | 显示全部楼层
像void a(A b){}这种函数一般用在什么地方?(这个函数有可能把实参的数据改变掉)
 楼主| 发表于 2007-12-4 11:01:24 | 显示全部楼层
  1. #include <stdio.h>

  2. class A
  3. {
  4. public:
  5.         char *p;
  6.         char q;
  7. public:
  8.         A()
  9.         {
  10.                 p = 0;
  11.                 printf("AAAA\n");
  12.         }
  13.         ~A()
  14.         {
  15.                 //if (p)
  16.                 //{
  17.                 //        delete p;
  18.                 //        p = 0;
  19.                 //}
  20.                 printf("~AAAA\n");
  21.         }
  22. };

  23. A a(A x)
  24. {
  25.         *x.p = 1;
  26.         x.q = 2;
  27.         return x;
  28. }

  29. A &b(A x)
  30. {
  31.         *x.p = 3;
  32.         x.q = 4;
  33.         return x;
  34. }

  35. A c(A &x)
  36. {
  37.         *x.p = 5;
  38.         x.q = 6;
  39.         return x;
  40. }

  41. A &d(A &x)
  42. {
  43.         *x.p = 7;
  44.         x.q = 8;
  45.         return x;
  46. }

  47. int main(int argc, int *argv[])
  48. {
  49.         A i;
  50.         A k;

  51.         i.p = new char(2);
  52.         i.q = 50;

  53.         k = a(i);
  54.         printf("%d %d\n", *k.p, k.q);
  55.         k = b(i);
  56.         printf("%d %d\n", *k.p, k.q);
  57.         k = c(i);
  58.         printf("%d %d\n", *k.p, k.q);
  59.         k = d(i);
  60.         printf("%d %d\n", *k.p, k.q);
  61.         return 0;
  62. }
  63. /*
  64. *出现:  AAAA
  65. *      AAAA
  66. *      ~AAAA
  67. *      ~AAAA
  68. *      1  2
  69. *      ~AAAA
  70. *      3  4
  71. *      ~AAAA
  72. *      5  6
  73. *      7  8
  74. *      ~AAAA
  75. *      ~AAAA
  76. */
复制代码
函数A a(A x);执行赋值语句后要返回x,但是返回前要析构x,那怎么返回x?
执行k = a(i);后要析构?
发表于 2007-12-4 12:16:20 | 显示全部楼层
原帖由 yan 于 2007-12-4 10:33 发表
像void a(A b){}这种函数一般用在什么地方?(这个函数有可能把实参的数据改变掉)


这个其实是你没有提供拷贝函数造成造成的.
默认情况下 A a =b;
会将类b的RAM copy 到类A所在地址,但这样一般是不合理的.

[ 本帖最后由 Eastsun 于 2007-12-4 12:23 编辑 ]
 楼主| 发表于 2007-12-4 13:34:40 | 显示全部楼层
拷贝构造函数是这样么?A::A(A &x){..........}
还有10#的问题呢?
发表于 2007-12-4 13:59:18 | 显示全部楼层
应该是在销毁前,已经赋值给左边那个了..
您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

Archiver|手机版|小黑屋|EMAX Studio

GMT+8, 2024-4-20 21:50 , Processed in 0.014505 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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