“引用”用我们那的话叫 reference
在搜狗百科上是这么解释的:
写文章时,有意引用 成语、 诗句、 格言、典故等, 以表达自己想要表达的思想感情,说明自己对新问题新道理的见解,这种 修辞手法叫引用。
写文章时,有意引用 成语、 诗句、 格言、典故等, 以表达自己想要表达的思想感情,说明自己对新问题新道理的见解,这种 修辞手法叫引用。
当然我们今天要讲的不是这样的引用,讲的是C++语法上的引用。
在C++的百度百科上是这么解释的:
引用引入了对象的一个同义词。 引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。定义引用的表示方法与定义指针相似。
引用引入了对象的一个同义词。 引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。定义引用的表示方法与定义指针相似。
简而言之 引用不是定义一个新的变量,而是给一个已经定义的变量重新起一个别名。
引用的声明方法:类型 &引用名=目标变量名;
int a=2;
int &ra=a;
int &ra=a;
a为目标原名称,ra为目标引用名。给ra赋值:ra=1; 等价于 a=1;
引用的特点:
1. 一个变量可取多个别名
2. 引用必须初始化
3. 引用只能在初始化的时候引用一次,不能改变为再引用其他的变量。
4. 引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。
5. 引用地址。&ra与&a相等,同一块内存空间。即我们常说引用名是目标变量名的一个别名。别名一词好像是说引用不占据任何内存空间。 但是编译器在一般将其实现为const指针,即指向位置不可变的指针。即引用实际上与一般指针同样占用内存。
2. 引用必须初始化
3. 引用只能在初始化的时候引用一次,不能改变为再引用其他的变量。
4. 引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。
5. 引用地址。&ra与&a相等,同一块内存空间。即我们常说引用名是目标变量名的一个别名。别名一词好像是说引用不占据任何内存空间。 但是编译器在一般将其实现为const指针,即指向位置不可变的指针。即引用实际上与一般指针同样占用内存。
代码块:
#include<stdio.h>
#include<iostream>
using namespace std;
void Test()
{
int a = 1;
int& b = a; //占用同一块内存空间
cout << "a:address->" << &a << endl;
cout << "b:address->" << &b << endl;
a = 2; //给a赋值,b一样改变
cout << "a--->" << a;
cout << " b--->" << b << endl;
b = 3;
cout << "a--->" << a;
cout << " b--->" << b << endl;
int& c = b; // 引用一个引用变量,别名的别名
c = 4;
cout << "a--->" << a ;
cout << " b--->" << b ;
cout << " c--->" << c << endl;
}
int main()
{
Test();
system("pause");
return 0;
}
运行结果:

const做引用
void Test1()
{
int d1 = 4;
const int & d2 = d1; //声明为const常量
cout << "d1--->" << d1;
cout << " d2--->" << d2 << endl;
d1 = 5; // d1改变 d2的值也会改变。
//d2 = 6; // 不能给常量(不能被修改的量)赋值
cout << "d1--->" << d1;
cout << " d2--->" << d2 << endl;
const int d3 = 1;
const int & d4 = d3; //类型相同
//int&d5 = d3; //类型不匹配
cout << "d3--->" << d3;
cout << " d4--->" << d4 << endl;
const int & d6 = 5; // 常量具有常性,只有常引用可以引用常量
double d7 = 1.1;
//int& d8 = d7; //d7是double类型,d8是int
const int& d9 = d7; //d9为int型,不能完全赋值
cout << "d7--->" << d7;
cout << " d9--->" << d9 << endl;
}
int main()
{
Test1();
system("pause");
return 0;
}
运行结果:

引用做参数
传统的c语言中,函数在调用时参数是通过值来传递的,这就是说函数的参数不具备返回值的能力。
所以如果需要函数的参数具有返回值的能力,往往是通过指针来实现的。
But,现在引用的出现完全解决了这一垄断的局面。 请看 ...
所以如果需要函数的参数具有返回值的能力,往往是通过指针来实现的。
But,现在引用的出现完全解决了这一垄断的局面。 请看 ...
Example:交换两个数
1.传统的指针做参数
void swap1(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
2.引用做参数
void swap(int &a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
}
int main()
{
int x = 2;
int y = 4;
cout << "x=" << x << " ""y=" << y << endl;
swap(x,y);
cout << "x=" << x << " ""y=" << y << endl;
system("pause");
return 0;
}
运行结果:

优点:
引用传递函数的参数,能保证参数传递中不产生临时变量,提高传递的效率,且通过const的使用,保证了引用传递的安全性。
引用做返回值
int& func(int& x)
{
int i = 0;
for (; i < 10; i++)
{
x++;
}
return x;
}
int main()
{
int x = 32;
func(x);
cout << "x=" << x << endl;
system("pause");
return 0;
}
运行结果:

引用作为返回值 一些规则:
(1)不能返回局部变量的引用。主要原因是局部变量会在函数返回后被销毁。
(2)不能返回函数内部new分配的内存的引用。可能会造成内存泄漏等问题。
(3)可以返回类成员的引用,但最好是const。
(4)引用作为函数返回值,这个值的生命周期一定比函数长
(2)不能返回函数内部new分配的内存的引用。可能会造成内存泄漏等问题。
(3)可以返回类成员的引用,但最好是const。
(4)引用作为函数返回值,这个值的生命周期一定比函数长
通过反汇编看引用
void func(int& x){ x++;}
反汇编:
void func(int& x)
{
009E4B80 push ebp
009E4B81 mov ebp,esp
009E4B83 sub esp,0C0h //记住这个0C0h,化成十进制为192
009E4B89 push ebx //寄存器的入栈
009E4B8A push esi
009E4B8B push edi
009E4B8C lea edi,[ebp-0C0h] //扩展新栈帧,将有效地址传给edi寄存器,即取偏移地址
009E4B92 mov ecx,30h //4*30h即4*48=192
009E4B97 mov eax,0CCCCCCCCh //初始化,未初始化则为烫烫烫烫....
009E4B9C rep stos dword ptr es:[edi] //rep指令:重复上面的指令,ecx的值是重复次数;
//stos指令:将eax的值拷贝esp中(即edi指向的地址)
x++;
009E4B9E mov eax,dword ptr [x] //局部变量x的创建,dword 通过指针赋值,ptr就是指针,相当于把x赋值给eax寄存器
009E4BA1 mov ecx,dword ptr [eax]
009E4BA3 add ecx,1 //x佳佳
009E4BA6 mov edx,dword ptr [x]
009E4BA9 mov dword ptr [edx],ecx
}
通过查看反汇编我们看见:
从底层来说,引用的实质是指针,但是---从高层语言级别来看,我们不能说引用就是指针,他们是两个完全不同的概念。我们可以这么说:从语言级别上,指针和引用没有关系,引用就是对象。不是指向对象的指针,也不是对象的拷贝,就是对象!!!
引用和指针异同点:
相同:
在底层实现方式相同,都是指针方式实现
在底层实现方式相同,都是指针方式实现
区别:
1.引用只能在定义时初始化一次,之后不能改变指向其它变量(从一而终);指针变量的值可变
2.引用必须指向有效的变量,指针可以为空。
3.sizeof指针对象和引用对象的意义不一样。sizeof引用得到的是所指向的变量的大小,而sizeof指针是对象地址的大小。
4.指针和引用自增(++)自减(--)意义不一样。
5.有多级指针,没有多级引用
6.相对而言,引用比指针更安全
1.引用只能在定义时初始化一次,之后不能改变指向其它变量(从一而终);指针变量的值可变
2.引用必须指向有效的变量,指针可以为空。
3.sizeof指针对象和引用对象的意义不一样。sizeof引用得到的是所指向的变量的大小,而sizeof指针是对象地址的大小。
4.指针和引用自增(++)自减(--)意义不一样。
5.有多级指针,没有多级引用
6.相对而言,引用比指针更安全