【转】C++标准转换运算符const_cast
const_cast转换符是用来移除变量的const或volatile限定符。
对于const变量,我们不能修改它的值,这是这个限定符最直接的表现。但是我们就是想违背它的限定希望修改其内容怎么办呢?
下边的代码显然是达不到目的的:
const int constant = ;
int modifier = constant;
因为对modifier的修改并不会影响到constant,这暗示了一点:const_cast转换符也不该用在对象数据上,因为这样的转换得到的两个变量/对象并没有相关性。
只有用指针或者引用,让变量指向同一个地址才是解决方案,可惜下边的代码在C++中也是编译不过的:
const int constant = ;
int* modifier = &constant
// Error: invalid conversion from 'const int*' to 'int*'
(上边的代码在C中是可以编译的,最多会得到一个warning,所在在C中上一步就可以开始对constant里面的数据胡作非为了)
把constant交给非const的引用也是不行的。
const int constant = ;
int& modifier = constant;
// Error: invalid initialization of reference of type 'int&' from expression of type 'const int'
于是const_cast就出来消灭const,以求引起程序世界的混乱。
下边的代码就顺利编译通过了:
const int constant = ;
const int* const_p = &constant;
int* modifier = const_cast<int*>(const_p);
*modifier = ;
为何要去除const限定?
从前面代码中已经看到,我们不能对constant进行修改,但是我们可以对modifier进行重新赋值。
但是但是,程序世界真的混乱了吗?我们真的通过modifier修改了constant的值了吗?修改const变量的数据真的是C++去const的目的吗?
如果我们把结果打印出来:
cout << "constant: "<< constant <<endl;
cout << "const_p: "<< *const_p <<endl;
cout << "modifier: "<< *modifier <<endl;
/**
constant: 21
const_p: 7
modifier: 7
**/
constant还是保留了它原来的值。
可是它们的确指向了同一个地址呀:
cout << "constant: "<< &constant <<endl;
cout << "const_p: "<< const_p <<endl;
cout << "modifier: "<< modifier <<endl; /**
constant: 0x7fff5fbff72c
const_p: 0x7fff5fbff72c
modifier: 0x7fff5fbff72c
**/
这真是一件奇怪的事情,但是这是件好事:说明C++里是const,就是const,外界千变万变,我就不变。不然真的会乱套了,const也没有存在的意义了。
IBM的C++指南称呼“modifier = 7;”为“未定义行为(Undefined Behavior)”。所谓未定义,是说这个语句在标准C++中没有明确的规定,由编译器来决定如何处理。
位运算的左移操作也可算一种未定义行为,因为我们不确定是逻辑左移,还是算数左移。
再比如下边的语句:v[i] = i++; 也是一种未定义行为,因为我们不知道是先做自增,还是先用来找数组中的位置。
对于未定义行为,我们所能做的所要做的就是避免出现这样的语句。对于const数据我们更要这样保证:绝对不对const数据进行重新赋值。
如果我们不想修改const变量的值,那我们又为什么要去const呢?
原因是,我们可能调用了一个参数不是const的函数,而我们要传进去的实际参数却是const的,但是我们知道这个函数是不会对参数做修改的。于是我们就需要使用const_cast去除const限定,以便函数能够接受这个实际参数。
#include <iostream>
using namespace std; void Printer (int* val,string seperator = "\n")
{
cout << val<< seperator;
} int main(void)
{
const int consatant = ;
//Printer(consatant);//Error: invalid conversion from 'int' to 'int*'
Printer(const_cast<int *>(&consatant)); return ;
}
出现这种情况的原因,可能是我们所调用的方法是别人写的。还有一种我能想到的原因,是出现在const对象想调用自身的非const方法的时候,因为在类定义中,const也可以作为函数重载的一个标识符。
使用const_cast去掉const属性,其实并不是真的改变原类类型(或基本类型)的const属性,它只是提供了一个接口(指针或引用 ),使你可以通过这个接口来改变类型的值。也许这也是const_cast只能转换指针或引用的一个原因吧。
【转】C++标准转换运算符const_cast的更多相关文章
- C++标准转换运算符const_cast
前面讲了C++继承并扩展C语言的传统类型转换方式,最后留下了一些关于指针和引用上的转换问题,没有做详细地讲述.C++相比于C是一门面向对象的语言,面向对象最大的特点之一就是具有“多态性(Polymor ...
- C++标准转换运算符
C++类型转换在实际编程中会经常使用,其实,本质上对象的类型用来解释(interpret)对象.因为,每个对象都占据一块内存空间,这块内存空间存放了一段二进制数据.通过标记该对象的类型,告诉如何看待这 ...
- C++标准转换运算符reinterpret_cast
C++标准转换运算符reinterpret_cast reinterpret_cast <new_type> (expression) reinterpret_cast运算符是用来处理无关 ...
- C++标准转换运算符 --四种
具体归纳如下: reinterpret_cast 函数将一个类型的指针转换为另一个类型的指针. 这种转换不用修改指针变量值存放格式(不改变指针变量值),只需在编译时重新解释指针的类型就可做到.rein ...
- 【转】C++标准转换运算符reinterpret_cast
reinterpret_cast<new_type> (expression) reinterpret_cast运算符是用来处理无关类型之间的转换:它会产生一个新的值,这个值会有与原始参数 ...
- C++标准转换运算符dynamic_cast
dynamic_cast <new_type> (expression) dynamic_cast运算符,应该算是四个里面最特殊的一个,因为它涉及到编译器的属性设置,而且牵扯到的面向对象的 ...
- const_cast标准转换运算符
#include <iostream> using namespace std; class A { public: A() { a=; } public: int a; }; void ...
- 【转】C++标准转换运算符static_cast
static_cast<new_type> (expression) 虽然const_cast是用来去除变量的const限定,但是static_cast却不是用来去除变量的static引用 ...
- C++标准转换运算符static_cast
该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性. 中文名 暂无 外文名 static_cast 分 类 强制类型转换 类 型 C++ s ...
随机推荐
- HDU - 6357 Hills And Valleys(DP)
http://acm.hdu.edu.cn/showproblem.php?pid=6357 题意 给一个数值范围为0-9的a数组,可以选择翻转一个区间,问非严格最长上升子序列,以及翻转的区间. 分析 ...
- ZOJ - 3450 Doraemon's Railgun (dp)
https://vjudge.net/problem/ZOJ-3450 题意 一座位落(X0,Y0)的城市将遭受n个敌人的摧残.现在我们手上有某科学的超电磁炮,每次攻击都是一条射线,对于共线的敌人,必 ...
- Linux下main函数启动过程【程序员自我修养笔记】【自用】
1. 入口函数和程序初始化 1.1 程序从main开始吗? 当程序执行到main函数的第一行时,很多事情都已经完成了: [证1]如下是一段C语言代码: 代码中可以看到,在程序刚刚执行到main的时候, ...
- java中的日志打印
java中的日志打印: 日志工具类: #获取日志 INFO:表示获取日志的等级 A1:表示日志存器,可以自定义名称 #===DEBUG INFO log4j.rootLogger=DEBUG,A1,A ...
- 基本数据类型转String,String转基本数据类型
基本数据类型 --> 字符串 1.基本数据类型+"" String s = 5 + ""; 2.使用包装类的静态方法toString(参数),参数是要转化 ...
- GeoGlobe Server运维
本篇博文简单记录鄙人在管理和维护GeoGlobe Server中,遇到的一些问题以及可行的解决方案 1 关于启动内存 Server默认的启动内存是256M,当服务比较多的时候,启动就会很慢.我们可以修 ...
- C# UpdatePanel加载完毕回调JS
如果 我们想UpdatePanel加载完成后做一些事情 需要使用js <script type="text/javascript"> //给ScriptManager的 ...
- json日期字符串格式化时间
var str = '/Date(1333245600000+0800)/'; function data_string(str) { var d = eval('new ' + str. ...
- nativefier - 快速把任意网页生成桌面应用程序
使用前端技术开发桌面应用的技术已经相当成熟了,像早先的 NW.js,如今很火的 Electron 等,都可以轻松实现.今天给大家分享的 nativefier 就是基于 Electron 封装的,可以帮 ...
- CountDownLatch学习
看了几篇博客,说用CountDownLatch实现一个先执行完子线程,再执行主线程的例子.因此写一篇博客总结一下. 一.CountDownLatch了解 1.CountDownLatch继承了Abst ...