C++引用的用法

来源:互联网 发布:裤子 知乎 编辑:程序博客网 时间:2024/05/22 00:27

什么是引用?

       引用就是某一变量或者某一目标的别名。对引用的操作就是对实际变量的操作。引用的声明方式:类型标识符 &引用名=目标变量名。

    (1)&在此不是求地址运算,而是起标识作用。
    (2)类型标识符是指目标变量的类型。
    (3)声明引用时,必须同时对其进行初始化。
    (4)引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。
       int a,&ra=a;
       a为目标原名称,ra为目标引用名。给ra赋值:ra=1; 等价于 a=1;
    (5)对引用求地址,就是对目标变量求地址。&ra与&a相等。即我们常说引用名是目标变量名的一个别名。别名一词好像是说引用不占据任何内存空间。但是编译器在一般将其实现为const指针,即指向位置不可变的指针。即引用实际上与一般指针同样占用内存。
    (6)不能建立引用的数组。因为数组是一个由若干个元素所组成的集合,所以无法建立一个由引用组成的集合。但是可以建立数组的引用.
例如: int& ref [3]= {2,3,5};//声明ref引用的数组错误
但是可以这样写:
const int (&ref)[3] ={2,3,5};
为什么要加上const ,因为{2,3,5}此时是个字面值数组,是保存在代码段里,只读的属性,如果不加,编译错误,而且后面对ref[0]的赋值也不会成功.
需要特别强调的是引用并不产生对象的副本,仅仅是对象的同义词。
     (7)引用必须在定义时马上被初始化,因为它必须是某个东西的同义词。你不能先定义一个引用后才
初始化它。例如下面语句是非法的:
Point &pt3;
pt3=pt1;
     (8)引用是除指针外另一个可以产生多态效果的手段。
这意味着,一个基类的引用可以指向它的派生类实例。例如:

class A;
class B: public A
{
   ...
};

B b;
A & aRef = b;    // 基类引用指向派生类

如果A类中定义有虚函数,并且在B类中重写了这个虚函数,就可以通过aRef产生多态效果。

 
下面是引用的使用例子,说明都在代码注释里了。
#include <iostream>using namespace std;void swap1(int a,int b);void swap2(int* a,int* b);void swap3(int& a,int& b);void swap4(const char* a,const char* b);void swap5(const char** a,const char** b);void swap6(const char*& a,const char*& b);int main(){int a = 10,b = 20;swap1(a,b);cout<<"swap1"<<" : "<<a<<" , "<<b<<endl;//输出10,20;swap2(&a,&b);cout<<"swap2"<<" : "<<a<<" , "<<b<<endl;//20,10swap3(a,b);cout<<"swap3"<<" : "<<a<<" , "<<b<<endl;//10,20 因为swap2已经交换了;const char* pa = "hello";const char* pb = "world";swap4(pa,pb);cout<<"swap4"<<" : "<<pa<<" , "<<pb<<endl;//hello,world;swap5(&pa,&pb);cout<<"swap5"<<" : "<<pa<<" , "<<pb<<endl;//world,hello;swap6(pa,pb);cout<<"swap6"<<" : "<<pa<<" , "<<pb<<endl;//world,hello;system("pause");return 0;}//值传递,只是形参的交换,并没有实现实参的交换;void swap1(int a,int b){int c = a;a = b;b = c;}//形参指向的是实参的地址,直接对实参地址内容的交换就是实参值的交换;void swap2(int* a,int* b){int c = *a;*a = *b;*b = c;}//引用交换,形参引用就是实参的别名,引用实质是指针,看上去交换的是形参的值,实际上交换的就是实参;void swap3(int& a,int& b){int c = a;a = b;b = c;}//因为实参本身就是指针,所以仍然是值传递,并没有对实参的地址交换;void swap4(const char* a,const char* b){const char* c = a;a = b;b = c;}//传递实参的地址,完成实参值的交换;void swap5(const char** a,const char** b){const char* c = *a;*a = *b;*b = c;}//使用指针的引用,实际上交换的就是实参;void swap6(const char*& a,const char*& b){const char* c = a;a = b;b = c;}//判断指针和引用的时候,需要从右向左读 例如 char ** a 则 a 是一个指针,指向另一个指针,而另一个指针指向的是char;//const char*& b 则 b 是一个引用,是一个指针的引用,而指针指向的是一个 const char;//引用的作用一般是为了节约效率,例如函数传递的参数是结构体,或者类,那么如果进行值传递,性能就比较低;//但是需要注意的是,引用一般搭配const类型一起使用。因为这样可以避免在参数传递时,由于程序员的失误导致的实参值篡改;//另外,引用还被用于函数的输出参数;//指针方式;double calcircle1(double r,double* area){*area = 3.14 * r * r;//圆的面积;return 2 * 3.14 * r;//圆的周长;}//调用方式;double area;double c = calcircle1(3,&area);//引用方式;double calcircle2(double r,double& area){area = 3.14 * r * r;//圆的面积;return 2 * 3.14 * r;//圆的周长;}//调用方式;double area;double c = calcircle2(3,area);

 

 

0 0