1.引用的概念
下面的写法定义了一个引用,并将其初始化为引用某个变量。
类型名 & 引用名 = 某变量名;
类型名 & 引用名 = 某变量名;
int n = 4;
int & r = n; // r引用了 n, r的类型是 int &
某个变量的引用,等价于这个变量,相当于该变量的一个别名。
示例程序:
int n = 4;
int & r = n;
r = 4;
cout << r; //输出4
cout << n; //输出4
n = 5;
cout << r; //输出5
2.3个注意点
定义引用时一定要将其 初始化成引用某个变量。
初始化后,它就一直引用该变量,
不会再引用别的变量了。
引用只能引用
变量,
不能引用
常量和
表达式。
double a = 4, b = 5;
double & r1 = a;
double & r2 = r1; // r2也引用 a
r2 = 10;
cout << a << endl; // 输出 10
r1 = b; // r1并没有引用b,只是赋值
cout << a << endl; //输出 5
3.引用作为函数形参
引用应用的简单示例。C语言中,如何编写交换两个整型变量值的函数?
void swap( int * a, int * b)
{
int tmp;
tmp = * a; * a = * b; * b = tmp;
}
int n1, n2;
swap(& n1,& n2) ; // n1,n2的值被交换
有了C++的引用:
void swap( int& a, int& b)
{
int tmp;
tmp = a; a = b; b = tmp;
}
int n1, n2;
swap(n1,n2) ; // n1,n2的值被交换
4.引用作为函数的返回值
int n = 4;
int & SetValue() { return n; }
int main()
{
SetValue() = 40;
cout << n;
return 0;
} //输出: 40
5.常引用
定义引用时,前面加const关键字,即为“常引用”
int n;
const int & r = n;
r 的类型是
const int &
不能通过常引用去修改其引用的内容:
int n = 100;
const int & r = n;
r = 200; //编译错
n = 300; // 没问题
6.常引用和非常引用的转换
const T & 和T & 是不同的类型!!!
T & 类型的引用或T类型的变量可以用来初始化const T & 类型的引用。
const T 类型的常变量和const T & 类型的引用则不能用来初始化T &类型的引用,除非进行强制类型转换。
(这个我的理解是,因为你去初始化的是引用,而引用要改变的是变量本身,所以当然不能拿const类型的东西(不管是const变量还是const引用)去初始化引用了,要用它们初始化引用,也只能初始化const类型的引用。
至于第一个const类型引用的初始化,随便都可以,因为常引用不会去改变其引用的内容。一切都很合理~
那总结一下,其实很简单,就是仅在初始化引用的时候需要注意一下: 不能拿const类型的东西初始化引用类型,因为引用类型可以改变它引用的东西。)
至于第一个const类型引用的初始化,随便都可以,因为常引用不会去改变其引用的内容。一切都很合理~
那总结一下,其实很简单,就是仅在初始化引用的时候需要注意一下: 不能拿const类型的东西初始化引用类型,因为引用类型可以改变它引用的东西。)
7.和指针的区别
C++的引用首先跟指针的最大区别就是引用不是一个对象,而指针是一个对象;其次引用在其定义时就要初始化,而指针可以不用。
8.例子:下面哪个没错?
A) int n = 4;
int & r = n * 5;//错,引用的不能是表达式
B) int n = 6;
const int & r = n;//错,常引用不能修改其引用的内容
r = 7;
C) int n = 8;
const int & r1 = n;
int & r2 = r1;//错,不能用常引用对引用初始化
D) int n = 8;
int & r1 = n;
const int r2 = r1;
以上内容依旧摘自:PKU C++程序设计在线课笔记
C++方面的很多内容书上都看过,但还是有些知识掌握得不是很好,借此课程快速复习一下,并做总结。“盗”了 PKU 两位不错的老师的课件,作为回报,打个广告:这课不错哈,大家快去学~
后面的学习笔记不再赘述出处。
9.补充,对常量进行引用
若要对常量进行引用,则编译器首先建立一个临时变量,然后将该常量的值置入临时变量中,对该引用的操作就是对该临时变量的操作。
关于引用的初始化有两点值得注意:
- 当初始化值是一个左值(可以取得地址)时,没有任何问题;
- 当初始化值不是一个左值时,则只能对一个const T&(常量引用)赋值。而且这个赋值是有一个过程的:首先将值隐式转换到类型T,然后将这个转换结果存放在一个临时对象里,最后用这个临时对象来初始化这个引用变量。
//例子:
double& dr = 1; // 错误:需要左值
const double& cdr = 1; // ok
//第二句实际的过程如下:
double temp = double(1);
const double& cdr = temp;
参考:
http://www.cnblogs.com/lbsx/archive/2009/08/28/1555581.html
常引用的补充
引用要引用正确的自身的类型,但是常量引用可以引用一个非const的对象,一个数,或者表达式。
参考: http://www.cnblogs.com/fusae-blog/p/4471787.html
int i = 42;
const int &r1 = i; //ok
const int &r2 = 42; //ok
const int &r3 = r1 * 2; //ok
int &r4 = r * 2; //error: 非常量引用不能引用一个表达式
让我们想想这是为什么?
double dval = 3014;
const int &ri = dval; //ok
其实编译器帮我们多做了一步
double dval = 3014;
const int temp = dval; //创建一个暂时的常量对象来存放dval
const int &ri = temp; //将引用到这个暂时的常量
正因为有这个无名的中转存量,所以常量引用才可以引用数,表达式,还有不同类型的对象。
参考: http://www.cnblogs.com/fusae-blog/p/4471787.html