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值,也 ...
随机推荐
- 有关MySQL数据库命令
phpstudy使用最终端打开数据库 : 第一次打开默认的密码是:root. 进入后对数据可以进行增删查改. show databases; 是查看数据库的指令 注意:分号是数据库的结束符,没有加分 ...
- 14JavaScript条件语句
条件语句用于基于不同的条件来执行不同的动作. 1.条件语句 通常在写代码时,您总是需要为不同的决定来执行不同的动作.您可以在代码中使用条件语句来完成该任务. 在 JavaScript 中,我们可使用以 ...
- jquery实现复选框的全选、全不选、反选
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- PHP读取excel表格,和导出表格
读取表格 public function excel(){ import("Common.Vendor.Excel.PHPExcel"); $filename="./fi ...
- [笔记] 升級到 Delphi 10.2 Tokyo 笔记
升級到 Delphi 10.2 Tokyo 笔记: 更新 Xcode 8.3 & iOS 10.3 测试: macOS 没问题(可 Debug) iOS Simulator 没问题(可 Deb ...
- 大二作业——操作系统实验——C语言用双向链表,模拟实现动态分区式存储管理
实验:动态分区式存储管理 实验内容: 编写程序模拟完成动态分区存储管理方式的内存分配和回收.实验具体包括:首先确定内存空闲分配表:然后采用最佳适应算法完成内存空间的分配和回收:最后编写主函数对所做工作 ...
- vue中-webkit-box-orient:vertical打包放到线上不显示
解决方法: 1.找到build文件夹 下的webpack.prod.conf.js文件 2.注释new OptimizeCSSPlugin({ css ...
- springcloud 笔记-服务注册中心
1.搭建springcloud服务注册中心需要添加eureka的依赖: <?xml version="1.0" encoding="UTF-8"?> ...
- 20155328 《Java程序设计》实验三 敏捷开发与XP实践 实验报告
一.编码标准 编程标准包含:具有说明性的名字.清晰的表达式.直截了当的控制流.可读的代码和注释,以及在追求这些内容时一致地使用某些规则和惯用法的重要性. 下面是没有最基本的缩进的一个程序: publi ...
- Dlib库中实现正脸人脸检测的测试代码
Dlib库中提供了正脸人脸检测的接口,这里参考dlib/examples/face_detection_ex.cpp中的代码,通过调用Dlib中的接口,实现正脸人脸检测的测试代码,测试代码如下: #i ...