引用
基本概念
定义︰引用是为已存在的变量取了一个别名,引用和引用的变量共用同一块内存空间。
引用就是某一变量(目标〉的一个别名,也就是说,它是某个己存在变最的另一个名字。对引用的操作与对变量名直接操作完全一样。
引用的初始化
类型标识符&引用变量名=目标变量名;
上述格式中,“&”并不是取地址操作符,而是起标识作用,标识所定义的标识符是一个引用。引用声明完成以后相当于口标变量有两个名称
#include<iostream>
using namespace std;
int main() {
int b = 1;
int& a = b;
int c = 3;
a = c;
#int &a = c; 错误 ,引用一旦初始化,其值就不能再更改,即不能再做别的变量的引用
cout << a << endl;
return 0;
}
#结果为3
引用的特点
●引用实体和引用类型必须为同种类型(引用在初始化时只能绑定左值不能绑定常量值)
●引用在定义时必须初始化并且不能被初始化为NULL,不能更改引用关系-》引用的底层使用指针常亮来实现的 int * const p如int &b;是错误的。
●引用一旦初始化,其值就不能再更改,即不能再做别的变量的引用(不可以改变引用关系)
●数组不能定义引用,因为数组是一组数据,无法定义其别名。
2.函数参数(避免拷贝构造节约时间成本空间成本),函数返回值避免拷贝构造
左值:能取到地址的 ( 有名字的都是左值) 变量:a,b,....
右值:不能取到地址 (没有名字的是右值) 常量:12 ,"asd” , 函数的返回值
左值引用:左值引用只能引用左值int b = 2 ; int &a = b;4.
右值引用:只能引用右值int &&a= 12;
万能引用:即可以引用左值也可以引用右值,拷贝构造函数使用的是万能引用既可以接受左值也可以接受右值
const int& a = b;
const int& c = 68;
int a1 = 68;
int &b1 = a1;
#int &b2 = 76;错,
int &&c1 = 76;
#int &&c1 = a1;错,
int a = 66;
const int& b = a;
const int& c = 12;
*/
/*
赋值:给一个已经存在的对象一个值int a ; a= 1;;
初始化:int a= 1;
*/
引用应用
C++增加引用的类型,主要的应用就是把它作为函数的参数,以扩充函数传递数据的功能,引用作函数参数时是区别于值传递与址传递的引用传递。
利用引用传递可以克服值传递与址传递中容易出现错误且程序的可读性差的缺点。直接操作变量,简单高效可读性又好。
引用 vs 指针主要的不同:
引用在定义时必须被初始化并且不能被初始化为NULL,指针没有要求,存在空指针
一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。(引用不能改变引用关系,指针随意)
有多级指针没有多级引用
引用++和指针++表达的含义不同。指针自增是指针上的计算,引用自增单纯加1
指针用sizeof计算大小结果不同,指针在32位内存下是四字节,在64位内存下是8字节,引用结果为类型大小
指针是一个实体,需要分配内存空间;引用只是变量的别名,不需要分配内存空间
引用与指针的区别
const
一句话让你彻底掌握const
const:首先作用于左边,如果左边没东西,就作用于右边
const int
int const
const int* const
int* const:指针本身不可改变,常量指针 //顶层
const int*:指针指向的内容不可改变 //底层
顶层 底层
顶层:对象本身是const
类中,const算入函数签名signature
const :
在类中常函数和非常函数也是重载关系:
不能修改成员变量,如果想修改成员变量需要在成员变量前加mutable 。常函数为什么不能修改成员变量:
常对象不能被修改,常对象只能调用常函数-》常函数不能修改成员变量,常函数中*this会被const修饰。
int *p;
int * const p;修饰 指针变量p不能被修改
const int *p;或者int const *p;修饰的是 *p不能被修改
const 的本质是修饰变量不能被修改,被const 修饰的是变量不是常量,在c语言中被const修饰的变量可以通过指针被修改
非常对象可以调用常函数,如果常函数和非常函数重载优先调用非常函数