1. 指针引用
顾名思义,指向指针的引用,比如
int* z=new int(10);
int *&z2=z; //(不可是&*)
修改z2的指向也会修改z的指向,修改*z2,*z也会被修改
2. const修饰符
const修饰的引用可以绑定普通引用,但普通引用不可以绑定const修饰的引用
int i=10;
int &i1 = i;
const int & i2 = i1;//正确,不可通过i2修改i1的值,但修改i1的值i2的值也会随之改变
int i=10;
const int & i2 = i;
int &i1 = i2;//错误,const int &不允许被更改,因此不可以用普通引用绑定
普通引用无法进行类型的转换,当引用类型和对象类型不同时会发生错误,但const修饰的引用则可以发生类型转换
double i=10.1;
int &i1 = i;//错误
const int &i2 = i;//正确
//const int & i2 = i;相当于
const int tmp = i;
const int &i2 = tmp;
3. constexpr和常量表达式
constexpr声明的变量一定是常量,并且必须用常量表达式初始化(常量,字面值等)
constexpr int mf = 20;//正确
constexpr int mf_1 = mf+1;//正确
constexpr int mf_2 = size();//错误,只有当size()是一个constexpr函数时才正确
constexpr指针初始值必须是nullptr或者0,或者存储在某个固定地址的对象(比如在函数体外的对象,函数体内的变量一般都不是存放在固定地址)
int a=10;
int main(){
int i=10;
constexpr int *i1 = &i;//错误,i地址不确定
constexpr int *i2 = &a;//正确,a地址确定
}
4.自动类型推导:auto
auto可以自动推导对象类型,但是不一定准确,它会丢弃引用和顶层const(表示变量不会改变,顶层const指针表示指针不可更改指向的对象,可更改指向对象的值,底层const表示指针表示指针不可更改指向对象的值,可以更改指向的对象,该说法和书上的一致,和网上的说法相反)
int i=0,&r = i;
auto a=r;//a的类型为int,而不是int &
const int ci=i,&cr = ci;
auto b = ci;//b类型为int,而不是const int
auto c = &i;c类型为int*
auto d = &ci;d类型为const int*,对常量对象取地址得到的是底层const
auto& f = i;//f类型为int&
5.自动类型推导:decltype
decltype也可进行类型推导,但是他只会得到对象的类型,不会计算他的值,相比于auto,decltype推导的类型更准确,他不会丢弃引用和顶层const
const int ci=0, &cj = ci;
decltype(ci) x = 0;//x类型为const int
decltype(cj) y = x;//y类型为const int&
//如果表达式内容是解引用操作,decltype得到引用类型
int z = 10;
int *p = &z;
decltype(*p) c;//错误,因为c是int&类型,必须初始化
//如果表达式加上括号,结果是引用
decltype((z)) d = z;d的类型是int&