C++:const_cast的简单理解
前言:const_cast是我比较头疼的一个知识点,最近查阅了很多资料,也翻看了很多他人的博客,故在此将自己目前学习到的有关const_cast知识做一个简单的总结
一、什么是const_cast
简单来说,const_cast是C++提供的四种显示类型转换的方式之一,其主要作用是移除变量的const限定符从而改变表达式的常量属性。
语法:const_cast<type_id>(expression);
特别注意:
(1) const_cast只能改变运算对象的底层const,也就是说:
•常量指针转化为非常量的指针,并且仍然指向原来的对象
•常量引用转化为非常量的引用,并且仍然指向原来的对象
const int value=;
int new_value=const_cast<int>(value); //错误:const_cast只能改变运算对象的底层const,而对顶层const无能为力(编译信息:[Error] invalid use of const_cast with type 'int', which is not a pointer, reference, nor a pointer-to-data-member type)
3
const int* value_ptr=&value;
int *ptr=const_cast<int*>(value_ptr);//正确:将常量指针转化为非常量指针,并仍然指向原来的对象 const int& value_re=value;
int& re=const_cast<int&>(value_re);//正确:将常量引用转化为非常量引用,并仍然指向原来的对象
(2) 不能用const_cast改变表达式的类型
const char* cp;
const_cast<string>(cp); //错误:const_cast不能改变表达式类型,只能改变常量属性
(3)使用const_cast把一个原本const的变量转换为非const是一个非定义行为(未定义行为指的是这个语句在标准C++中没有的规定,由编译器来决定如何处理)
const int value=;
const int* value_ptr=&value;
int* ptr=const_cast<int*>(value); //通过ptr写值是未定义行为
*ptr=;
由上面这个例子可以看出,在C++中对于添加const关键字的变量,其就是常量,不必担心其他机制(如const_cast)会改变其值。而对于未定义行为,应当尽量避免出现这样的语句
二、什么时候使用const_cast
在C++中,用指向非常量的指针来指向常量对象是非法的
const int value=;
int* ptr=&value;//错误: invalid conversion from 'const int*' to 'int*'
同样,用对非常量的引用绑定常量对象是非法的
const int value=;
int &new_value=value; //错误:invalid initialization of reference of type 'int&' from expression of type 'const int'
但另一方面,在C++编程过程中可能会出现某些变量原本不是const对象,但由于某些特殊的原因,在编程者不经意的情况下将其转换为了const对象,从而引发以上的错误,此时就需要cosnt_cast来消除const的影响
例如:
1.一个函数的参数不是const对象,并且编程者事先已经知道在这个函数中不会对参数进行修改,但需要传递的实参却是已经定义好的const对象。为了成功调用这个函数,就需要利用到const_cast在实参传递前对其进行处理,从而使函数能够成功接收这个实参
#include<iostream>
using namespace std;
void Function(int *val){
cout<<*val<<endl;
}
int main(){
const int value=;
Function(const_cast<int*>(&value));
return ;
}
2.如果我们定义了一个非const的变量,却使用了一个指向const对象的指针来指向它,而在程序的某处希望改变这个变量时发现只有指针可用,此时就可以const_cast进行处理
#include<iostream>
using namespace std;
int main(){
int value=;
const int* const_ptr=&value;
int* ptr=const_cast<int*>(const_ptr);
*ptr=;
cout<<"value:"<<value<<endl;
cout<<"*const_ptr:"<<*const_ptr<<endl;
cout<<"ptr:" <<*ptr<<endl;
return ;
}
C++:const_cast的简单理解的更多相关文章
- git的简单理解及基础操作命令
前端小白一枚,最近开始使用git,于是花了2天看了廖雪峰的git教程(偏实践,对于学习git的基础操作很有帮助哦),也在看<git版本控制管理>这本书(偏理论,内容完善,很不错),针对所学 ...
- 简单理解Struts2中拦截器与过滤器的区别及执行顺序
简单理解Struts2中拦截器与过滤器的区别及执行顺序 当接收到一个httprequest , a) 当外部的httpservletrequest到来时 b) 初始到了servlet容器 传递给一个标 ...
- [转]简单理解Socket
简单理解Socket 转自 http://www.cnblogs.com/dolphinX/p/3460545.html 题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公 ...
- Js 职责链模式 简单理解
js 职责链模式 的简单理解.大叔的代码太高深了,不好理解. function Handler(s) { this.successor = s || null; this.handle = funct ...
- Deep learning:四十六(DropConnect简单理解)
和maxout(maxout简单理解)一样,DropConnect也是在ICML2013上发表的,同样也是为了提高Deep Network的泛化能力的,两者都号称是对Dropout(Dropout简单 ...
- Deep learning:四十二(Denoise Autoencoder简单理解)
前言: 当采用无监督的方法分层预训练深度网络的权值时,为了学习到较鲁棒的特征,可以在网络的可视层(即数据的输入层)引入随机噪声,这种方法称为Denoise Autoencoder(简称dAE),由Be ...
- 简单理解dropout
dropout是CNN(卷积神经网络)中的一个trick,能防止过拟合. 关于dropout的详细内容,还是看论文原文好了: Hinton, G. E., et al. (2012). "I ...
- 我们为之奋斗过的C#-----C#的一个简单理解
我们首先来简单叙述一下什么是.NET,以及C#的一个简单理解和他们俩的一个区别. 1 .NET概述 .NET是Microsoft.NET的简称,是基于Windows平台的一种技术.它包含了能在.NET ...
- 简单理解ECMAScript2015中的箭头函数新特性
箭头函数(Arrow functions),是ECMAScript2015中新加的特性,它的产生,主要有以下两个原因:一是使得函数表达式(匿名函数)有更简洁的语法,二是它拥有词法作用域的this值,也 ...
随机推荐
- Selenium+Chrome或Firefox的动态爬虫程序
新版本的Selenium不再支持PhantomJS了,请使用Chrome或Firefox的无头版本来替代.
- laravel when 的用法
当你在使用where语句有前提条件时,比如某值为1的时候才执行where子句,否则不执行,这个时候,laravel5.5新出了一个简便方法when($arg,fun1[,fun2]). 具体用法如下: ...
- else的妙用--if-else 成对出现,可以检测意外的放生,方便找bug
else用于意外情况的检测.可以写入log,或者串口打印出来. 养成这样的习惯,好处 1 提高程序稳定性,可靠性. 2 遇到bug有头绪.
- 用GO写一个连接比特币JSONRPC接口的程序
比特币钱包默认是不开启JSONRPC接口的,要在比特币区块文件夹下新建bitcoin.conf这个文件,并写入以下内容 server=1 rpcuser=xxmm rpcpassword=1234 ...
- go语言的cron包的简单使用
3.cron举例说明 每隔5秒执行一次:*/5 * * * * ? 每隔1分钟执行一次:0 */1 * * * ? 每天23点执行一次:0 0 ...
- 20155211 2016-2017-2 《Java程序设计》第四周学习总结
20155211 2016-2017-2 <Java程序设计>第四周学习总结 教材学习内容总结 这周的内容感觉较上周相比难度增加 教材学习中的问题和解决过程 刚开始学习第六章的时候的时候敲 ...
- # 学号20155308 2006-2007-2 《Java程序设计》第4周学习总结
学号20155308 2006-2007-2 <Java程序设计>第4周学习总结 教材学习内容总结 6.1 何谓继承 继承基本上就是避免多个类间重复定义共同行为. 许多类之间具有相同的属性 ...
- Oracle下如何设置 log_archive_dest
一:存在 DB_RECOVERY_FILE_DEST 时,如何设置 LOG_ARCHIVE_DEST: SQL> archive log listデータベース・ログ・モード アーカイブ・モード自 ...
- 1071: [SCOI2007]组队
1071: [SCOI2007]组队 https://lydsy.com/JudgeOnline/problem.php?id=1071 分析: dp+单调性. A*(hi–minH)+B*(si–m ...
- WPF获取窗口句柄
通过WPF的互操作帮助类WindowInteropHelper,相关连接:https://msdn.microsoft.com/zh-cn/library/system.windows.interop ...