前言: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的简单理解的更多相关文章

  1. git的简单理解及基础操作命令

    前端小白一枚,最近开始使用git,于是花了2天看了廖雪峰的git教程(偏实践,对于学习git的基础操作很有帮助哦),也在看<git版本控制管理>这本书(偏理论,内容完善,很不错),针对所学 ...

  2. 简单理解Struts2中拦截器与过滤器的区别及执行顺序

    简单理解Struts2中拦截器与过滤器的区别及执行顺序 当接收到一个httprequest , a) 当外部的httpservletrequest到来时 b) 初始到了servlet容器 传递给一个标 ...

  3. [转]简单理解Socket

    简单理解Socket 转自 http://www.cnblogs.com/dolphinX/p/3460545.html  题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公 ...

  4. Js 职责链模式 简单理解

    js 职责链模式 的简单理解.大叔的代码太高深了,不好理解. function Handler(s) { this.successor = s || null; this.handle = funct ...

  5. Deep learning:四十六(DropConnect简单理解)

    和maxout(maxout简单理解)一样,DropConnect也是在ICML2013上发表的,同样也是为了提高Deep Network的泛化能力的,两者都号称是对Dropout(Dropout简单 ...

  6. Deep learning:四十二(Denoise Autoencoder简单理解)

    前言: 当采用无监督的方法分层预训练深度网络的权值时,为了学习到较鲁棒的特征,可以在网络的可视层(即数据的输入层)引入随机噪声,这种方法称为Denoise Autoencoder(简称dAE),由Be ...

  7. 简单理解dropout

    dropout是CNN(卷积神经网络)中的一个trick,能防止过拟合. 关于dropout的详细内容,还是看论文原文好了: Hinton, G. E., et al. (2012). "I ...

  8. 我们为之奋斗过的C#-----C#的一个简单理解

    我们首先来简单叙述一下什么是.NET,以及C#的一个简单理解和他们俩的一个区别. 1 .NET概述 .NET是Microsoft.NET的简称,是基于Windows平台的一种技术.它包含了能在.NET ...

  9. 简单理解ECMAScript2015中的箭头函数新特性

    箭头函数(Arrow functions),是ECMAScript2015中新加的特性,它的产生,主要有以下两个原因:一是使得函数表达式(匿名函数)有更简洁的语法,二是它拥有词法作用域的this值,也 ...

随机推荐

  1. MySQL->AUTO_INCREMENT[20180516]

    MySQL表格中自增长主键AUTO_INCREMENT使用,实现序列的最简单的方式   创建一个AUTO_INCREMENT自增的表 mysql> create table seq_test( ...

  2. Docker 学习笔记 (一)Dockerfile 创建本地镜像

    一.测试环境 OS version: CentOS Linux release 7.5.1804 (Core) docker cluster : master 1 + data node 4 dock ...

  3. 浅谈OSI七层网络模型和TCP/IP四层模型

    OSI七层网络模型 OSI(Open System Interconnection)开放系统互连参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系. OSI七层模型 功能 ...

  4. Git很简单--图解攻略

    Git Git 是目前世界上最先进的分布式版本控制系统(没有之一) 作用 源代码管理 为什么要进行源代码管理? 方便多人协同开发 方便版本控制 Git管理源代码特点 1.Git是分布式管理.服务器和客 ...

  5. 【转】ruby rake执行rspec

    RSpec 是Ruby的一个行为驱动开发(BDD)工具,当前的版本是 2.10.根据其入门文档,安装好之后,可以使用 rspec 命令来运行“测试”.但在某些情况下,如果参数较多,使用该命令并不方便: ...

  6. 20155233 2016-2017-2《Java程序设计》课程总结

    20155233 2016-2017-2<Java程序设计>课程总结 每周作业链接汇总 预备作业1:预习去写博客,如何达到理想的师生关系. 预备作业2:对自己C语言的学习进行了解与认识. ...

  7. 20155325《Java程序设计》实验一(Java开发环境的熟悉)实验报告

    实验一Java开发环境的熟悉-1 提交 Linux或Window或macOS中命令行下运行Java的截图 运行结果包含自己学号等证明自己身份的信息 实验一Java开发环境的熟悉-2 提交 Linux或 ...

  8. 20145207 实验二《Java面向对象程序设计》实验报告

    20145207 实验二<Java面向对象程序设计>实验报告 实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握UML建模 4.熟悉S.O ...

  9. 【SQLSERVER】服务挂起解决办法

    一. 问题描述:某项SQLSERVER服务,运行状态为“正在挂起更改”,导致该服务无法使用,也不能启动.停止.重新启动. 二.解决方法 方法一:从任务管理器 → 进程 (勾上 显示所有用户进程) → ...

  10. QT-2D编程

    QT-[转]2D编程 Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕上和绘图·设备上进行绘制,主要基于QPainter.QPainterDevice和QPainterEngine这3个类. ...