分享

C++引用

 复杂网络621 2014-09-12

  独立引用

“引用(reference)”与指针象似但不是指针。引用主要有3种用法:
  • 单独使用(一般称为“独立引用”);
  • 作参数使用;
  • 作返回值使用。

从功能上来说,引用型变量又可以看做事被引用变量的“别名”,这两个变量只是名称不同,变量的地址是同一个(共用体中的元素也是一样)。使用“引用”的好处主要是可以“逆向引用”。

常量也可以被引用,例如:“const int &ref = 10;”,这也是正确的,但这样定义无任何意义。定义独立引用时需要注意以下规则:
  • 引用型变量在定义时必须初始化。
  • 被引用的对象必须已经分配了空间,即不能为空,或空指针。
  • 被引用的对象不能为地址,即指针变量、数组变量等不能被引用。

变量引用举例:
  1. #include <iostream>
  2. using namespace std;
  3. int main( )
  4. {
  5. int a ;
  6. int &b = a; //b和a实际上是同一变量
  7. b = 100; //b赋值为100,也就是a赋值为100
  8. cout << a << endl;
  9. //a的地址和b的地址应该是完全一样
  10. cout << &a << endl;
  11. cout << &b << endl;
  12. /*-------▼下面代码有错,注释后才能运行▼-----------
  13. int x[] = {12,15,20} ;
  14. int &y = x; //错误:数组、指针不能被引用
  15. int x1;
  16. int &y1; //错误:引用时必须初始化
  17. y1 = x1;
  18. -------▲上面代码有错,注释后才能运行▲-----------*/
  19. return 0;
  20. }
输出结果:
100
0034F84C
0034F84C

函数的参数引用

许多教程在讲解参数引用时都喜欢选择交换两参数内容的swap(int &x, int &y)函数作例子,这的确很容易说明清楚,但并不能说这种用法优于指针作参数。
  1. #include <iostream>
  2. using namespace std;
  3. //|右边为指针作参数的代码,仅作比较用。
  4. void swap(int &x, int &y); //|void swap(int *x, int *y);
  5. //|
  6. int main ( ) //|
  7. { //|
  8. int i = 12; //|
  9. int j = 25; //|
  10. cout << "i=" << i << " j=" << j << endl; //|
  11. //|
  12. swap(i, j); //|swap(&i, &j);
  13. cout << "i=" << i << " j=" << j << endl; //|
  14. //|
  15. return 0; //|
  16. } //|
  17. //|
  18. void swap(int &x, int &y) //|void swap(int *x, int *y)
  19. { //|{
  20. int t; //| int t;
  21. //|
  22. t = x; //| t = *x;
  23. x = y; //| *x = *y;
  24. y = t; //| *y = *x;
  25. } //|}
运行结果:
i=12    j=25
i=25    j=12

对象引用作参数

初学者可以先跳过这一节,待学完“类”之后再来看。
  1. #include <iostream>
  2. using namespace std;
  3. class myclass {
  4. int who;
  5. public:
  6. myclass(int n) {
  7. who = n;
  8. cout << "构造函数调用" << who << endl;
  9. }
  10. ~myclass() {
  11. cout << "析构函数调用" << who << endl;
  12. }
  13. int id() {
  14. return who;
  15. }
  16. };
  17. void f1(myclass o) { //普通变量方式传递参数
  18. cout << "外部函数调用" << o.id() << endl;
  19. }
  20. void f2(myclass *o) { //指针方式传递参数
  21. cout << "外部函数调用" << o->id() << endl;
  22. }
  23. void f3(myclass &o) { //引用方式传递参数
  24. cout << "外部函数调用" << o.id() << endl;
  25. }
  26. int main ( )
  27. {
  28. myclass x1(1);
  29. f1(x1);
  30. cout << "-------" << endl;
  31. myclass x2(2);
  32. f2(&x2);
  33. cout << "-------" << endl;
  34. myclass x3(3);
  35. f3(x3);
  36. cout << "-------" << endl;
  37. return 0;
  38. }
运行结果:


从上面例子可以看出,用普通变量方式传递参数时,函数首先将参数复制一个副本,在函数体内使用的是副本。这个副本和参数自身不是同一个地址。而指针方式和引用方式并不产生副本,函数体内用的真是参数自身。需要注意的是,产生副本时调用了类的缺省“拷贝构造函数”,这个“拷贝构造函数”并不调用构造函数就产生了一个副本,有关详细内容参见后面章节。

作为函数返回值的引用类型

下面的代码略有深度,初学者如果无法理解请跳过。请先看下面的程序,有没有问题?
  1. #include <iostream>
  2. using namespace std;
  3. int &f();
  4. int x;
  5. int main ( )
  6. {
  7. f() = 100;
  8. cout << x << endl;
  9. return 0;
  10. }
  11. int &f()
  12. {
  13. return x;
  14. }
许多人都认为第9句错了,少数人认为第4句可能有问题。事实上,这个程序完全正确。

上面这个函数的返回值是引用类型,通过函数结果的设置反过来去改变“源头”数据,这种“逆向引用”为C++增强了很多功能,当然也有许多需要注意的地方。

由于本教程面向初学者,因此到此为止,不再深入下去,。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多