您现在的位置是:首页 >技术杂谈 >【C++】关于常引用的问题 #什么是权限放大?权限放小?隐式或强制转换居然还有这一步?...#网站首页技术杂谈
【C++】关于常引用的问题 #什么是权限放大?权限放小?隐式或强制转换居然还有这一步?...#
简介【C++】关于常引用的问题 #什么是权限放大?权限放小?隐式或强制转换居然还有这一步?...#
前言
引用
在c++
中的使用非常常见,可以说是很重要的,引用
的常引用
相关的问题让很多人稍不留神就出错了,这里我们就来谈谈常引用
的问题。
关于权限
- 关于权限有
权限缩小
和权限放大
的问题,比如一个文件,当初它只有读
的权限,而现在你给它再加个写
的权限,这就是权限放大
;又或当初它读,写
的权限都有,但你把他某个权限或所有权限都限制了,这就是权限缩小
。- 在
指针
和引用
赋值中,权限可以缩小
,但不可以放大
:这里通常指的是变量的值可不可以改的问题,如果说是从改到不能改,这就是将权限缩小了,这是可行的;如果说是从不能改到能改,这就是权限放大了,此时是不行的。- 而引用相当于
起别名
,对于这个别名的权限相对于本名变量有什么变化,这需要自己来决定。当自己决定别名的权限之后(不能与第二点表达的起冲突
),对它的使用就要留个心眼
。
关于引用与const
const
通常就是用来限制变量可以改,也就是这个变量的值不能被修改,结合上面的权限问题,我们来看以下例子:
1.
int a = 10;
const int& ra = a; // ??
int& raa = ra; // ??
2.
const int b = 20;
int& rb = b; // ??
const int& rrb = b; // ??
-
对于上述代码的第一种情况:
- 关于
ra
,ra
是a
的别名,并且被const
修饰,此时ra
的值是不能被修改的(要注意,这里单指ra
,只是说不能使用ra
对a
的值进行修改,使用a
修改值还是可以的,注意是单指ra
这个别名),由a
到ra
,很明显改的权限没了,属于权限变小
,是可行的。 - 关于
rra
,rra
是ra
的别名,也就是a
的别名的别名,本质还是一样的,只不过说,rra
是相对于ra
起的别名,ra
的权限不能改,而rra
前面没有const
(能读能改),所以由ra
到rra
属于权限放大
,是不可行的。
- 关于
-
对于上述代码的第二种情况:
- 关于
rb
,rb
是b
的别名,b
前面使用了const
修饰,说明它不能被修改,而rb
前面没有const
,说明可读可改,属于权限放大
,是不可行的。 - 关于
rrb
,rrb
也是b
的别名,b
前面使用了const
修饰,rrb
前面也使用了const
修饰,权限没有变
,当然可行。
- 关于
当我们在使用引用的时候,若是有const出现,那一定要注意权限的问题,不然程序写完一运行全是问题。
关于那秘密的一步
这秘密的一步还是与权限有关,居然是与权限有关,那么指向的对象就只有指针和引用了。
对于这秘密
的一步,我们先来看以下例子:
double b = 13.14;
//1.
int a = b; // 隐式类型转换
int c = (int)b; // 强制类型转换
//2.
// 2.1. // 隐式类型转换
int& rb = b; // 出错
const int& rrb = b;
// 2.2. // 强制类型转换
int& rrrb = (int)b; // 出错
const int& rrrrb = (int)b;
- 情况
1
:对于情况1
,据前面的概念,变量a
和c
既不是指针
也不是引用
,所以这里当然是可行的。 - 情况
2
:
2.1
:rb
是b
的别名,只不过rb
的类型是(int)
,b
的类型是(double)
,所以b
发生了隐式类型转换
,那么这里为什么会出错呢?就是因为那秘密的一步:b的隐式类型转换,转换后的值会先交给一个临时变量tmp(此时tmp变为13),而语法规定,这个tmp是一个常量,当tmp的值再交给rb时,rb是一个别名,前面没有const修饰,具有改的权限,所以这里权限是放大了的,是不可行的。也因此这里会出错。而下一条语句,rrb
前面有const
修饰,所以没有出错。
2.2
:有了2.1
的铺垫,实际上强转不强转的无所谓,最终还是归咎到有关const
的权限问题
,所以要理解那个tmp
,也因此这里的rrrb
会出错。
当然,对于函数调用,也有相关问题:
1.
void fun(int& rb) // 权限放大,不行
{
cout << rb << endl;
}
double b = 13.14;
fun(b); // 隐式类型转换交给一个临时变量,这个临时变量是常量
2.
void fun(const int& rb) // 权限不变,可行
{
cout << rb << endl;
}
double b = 13.14;
fun(b); // 隐式类型转换交给一个临时变量,这个临时变量是常量
-
无论是函数的传参还是返回,都存在那个临时变量的问题,规定了临时变量是一个常量,那就要小心这个点带来的问题。
-
对于
1,2
,关注的点还是一样的,都是围绕一个权限
的问题,所以当我们在对函数传参
或者是接收函数返回值
的时候,要注意要不要加const
,这样才能在小的细节上不会出错。
写在最后
最后还是要强调,关于本章内容,一定要清楚,不能搞混,谁知道在以后写代码的时候会不会出类似错误呢?而一旦出现此类的问题,那就很难受了。可能一时半会都想不清楚到底是哪出了问题。
感谢阅读本小白的博客,错误的地方请严厉指出噢!
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。